home *** CD-ROM | disk | FTP | other *** search
/ Dr. Windows 3 / dr win3.zip / dr win3 / NEW_TECH / JX4NT1.ZIP / JAX4TH.A < prev    next >
Text File  |  1993-12-30  |  112KB  |  4,480 lines

  1.     TITLE    jax4th.asm
  2.     PAGE    ,116
  3.  
  4. ; jax4th.a ... 32-bit ANS Forth for Windows NT
  5. ; copyright (c) 1993 by jack j. woehr
  6. ; p.o. box 51, golden, co 80402-0051
  7. ; jax@well.sf.ca.us | JAX on GEnie | 72203.1320@compuserve.com
  8. ; sysop, rcfb (303) 278-0364
  9.  
  10.     COMMENT    !
  11. This program is free software; you can redistribute it and/or modify
  12. it under the terms of the GNU General Public License as published by
  13. the Free Software Foundation; either version 2 of the License, or
  14. (at your option) any later version.
  15.  
  16. This program is distributed in the hope that it will be useful,
  17. but WITHOUT ANY WARRANTY; without even the implied warranty of
  18. MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  19. GNU General Public License for more details. (doc\license.txt)
  20.  
  21. You should have received a copy of the GNU General Public License
  22. along with this program; if not, write to the Free Software
  23. Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.  */
  24. !
  25.  
  26.     .386P
  27.     .XLIST
  28. include listing.inc    ; this may not be needed
  29.     .LIST
  30. include jax4th.i
  31.  
  32. _TEXT    SEGMENT DWORD USE32 PUBLIC 'CODE'
  33. _TEXT    ENDS
  34. _DATA    SEGMENT DWORD USE32 PUBLIC 'DATA'
  35. _DATA    ENDS
  36.  
  37.     ASSUME    CS: FLAT, DS: FLAT, SS: FLAT
  38.  
  39. _DATA    SEGMENT DWORD USE32 PUBLIC 'DATA'
  40.  
  41.     .SALL    ; suppress listing of Unicode macro expansion
  42.  
  43. myMsg:        unicode <Jax4th for Windows NT>
  44.         DW 0ah, 0dh
  45.         unicode <Copyright (c) 1993, Jack J. Woehr>
  46.         DW 0ah, 0dh
  47.         unicode <Covered under the GNU Public License.>
  48.         DW 0ah, 0dh
  49. myMsgLen    = ($-myMsg)/tchar
  50. orderMsg0:    unicode <Search Order: >
  51. orderMsg0Len    = ($-orderMsg0)/tchar
  52. orderMsg1:    unicode <Current Compilation Wordlist: >
  53. orderMsg1Len    = ($-orderMsg1)/tchar
  54. throwMsg:    unicode    <THROW #>
  55. throwMsgLen    = ($-throwMsg)/tchar
  56. byeMsg:        unicode <Bye>
  57.         DW 0ah, 0dh
  58. byeMsgLen    = ($-byeMsg)/tchar
  59. gnuMsg:        unicode < Jax4th 1.06 (C) 1993 Jack J. Woehr>
  60.         DW 0ah, 0dh
  61.         unicode < Jax4th comes with ABSOLUTELY NO WARRANTY.>
  62.          DW 0ah, 0dh
  63.            unicode < This is free software, and you are welcome to redistribute it >
  64.         DW 0ah, 0dh
  65.             unicode    < under certain conditions. See file COPYING.TXT for more info.>
  66.         DW 0ah, 0dh
  67.             unicode    < Type ABOUT to see this message again.>
  68.         DW 0ah, 0dh
  69. gnuMsgLen    = ($-gnuMsg)/tchar
  70.  
  71. ;--( Forth Messages )
  72.  
  73. okPrompt:    dw    3
  74.         unicode    < ok>
  75. listMsg1:    dw    7
  76.         unicode    <Block: >
  77. listMsg2:    dw    9
  78.         unicode    <File ID: >
  79. stackUnderMsg:    dw    12    
  80.         unicode    <Stack under.>
  81. undefinedMsg    dw    10
  82.         unicode    <Undefined.>
  83. compOnlyMsg    dw    17
  84.         unicode <Compilation only.>
  85. toBodyMsg    dw    22
  86.         unicode    <Not a child of CREATE.>
  87. blockWriteMsg    dw    18
  88.         unicode    <BLOCK write error.>
  89. blockReadMsg    dw    17
  90.         unicode    <BLOCK read error.>
  91. blockNumMsg    dw    21
  92.         unicode    <Invalid BLOCK number.>
  93. fileIOMsg    dw    20
  94.         unicode    <File I/O exception: >
  95. cStackMsg    dw    20
  96.         unicode    <Control stack error.>
  97. conStructMsg    dw    26
  98.         unicode    <Control structure mismatch.>
  99. zeroStringMsg    dw    17
  100.         unicode    <Zero-length name.>
  101. srchOverMsg    dw    22    
  102.         unicode <Search order overflow.>
  103. srchUnderMsg    dw    23
  104.         unicode <Search order underflow.>
  105. compNestMsg    dw    17
  106.         unicode <Compiler nesting.>
  107.  
  108. ;--( Various Messages )
  109.  
  110. dumpHdr:    dw    56
  111.         unicode    <Address  0100 0302 0504 0706 0908 0B0A 0D0C 0F0E Unicode>
  112.  
  113. unnamedHdr:    dw    7
  114.         unicode    <UNNAMED>
  115.  
  116. wlHdr:        dw    11
  117.         unicode    <Wordlists: >
  118.     .XALL                ; back to normal listing of macro expansion
  119.  
  120. ;--( Kernel Variables)
  121.  
  122. numWritten    DD    ?                ; for calls to WriteConsoleW
  123. secAttrib    SECURITY_ATTRIBUTES    <>        ; for calls to CreateFileW
  124. fileInfo    _BY_HANDLE_FILE_INFORMATION    <>    ; for calls to GetFileInformationByHandle
  125. numRead        DD    ?                ; number of chars read
  126. distMoveHigh    DD    ?                ; used by REPOSITION-FILE
  127. lastReadConW    DW    ?                ; used by KEY and others
  128.  
  129. inRecArray    INPUT_RECORD    256    DUP    (<>)    ; for KEY?
  130.  
  131. _DATA    ENDS
  132.  
  133. _TEXT    SEGMENT DWORD USE32 PUBLIC 'CODE'
  134.  
  135. ;-------------------------------;
  136. ;    Define API Entry    ;
  137. ;-------------------------------;
  138.  
  139. PUBLIC    _mainCRTStartup            ; satisfies console subsystem
  140.  
  141. ;-----------------------;
  142. ;    Main Program    ;
  143. ;-----------------------;
  144.  
  145. _mainCRTStartup    PROC NEAR    ; enter program
  146. ;--( Console subsys code swiped from entry after the C runtime startup. Without this code, Console API doesn't work!)
  147. ;--( This is still a bif of a mystery to us.)
  148.     push    ebp
  149.     mov    ebp, esp
  150.     sub    esp, 20
  151.     push    ebx
  152.     push    esi
  153.     push    edi
  154. ;--( End of apparently obligatory prelude)
  155.     cld            ; !!!***!!! NEXT depends on it, it's this way at boot anyway, but for good luck!
  156.     jmp    boot        ; apropos the above, see MOVE
  157.  
  158. ;---------------;
  159. ;    Forth    ;
  160. ;---------------;
  161.  
  162. ;--( Execution )
  163.  
  164.             ; Implementation detail
  165.     zname    <NEST>    ; this doesn't have an exe engine, it *is* one, musn't be called from Forth interpretively
  166. nest:    pushrp    ip        ; @(--RP) := IP
  167.     lea    ip,cell[wp]    ; IP := @(WP+4)
  168.     next
  169.  
  170.     zname    <DOCONST>        ; -- x    
  171.     push    DWORD PTR cell[wp]    ; Implementation detail
  172.     next                ; Execution engine, works for VARIABLE, also
  173.  
  174.     zname    <DODOES>        ; -- x        ; Implementation detail
  175.     push    DWORD PTR cell[wp]    ; push data pointer for this CREATE child
  176.     mov    wp,2*cell[wp]        ; WP := xt for DOES> code
  177.     dereftok            ; now is a pointer
  178.     jmp    nest        
  179.  
  180.     zname    <UNNEST>    ; -- x    R: nest-sys --
  181.     docode            ; Implementation detail
  182.     poprpto    ip        ; IP := @RP++
  183.     next
  184.  
  185. ; Same routine as above but different for a debugger to recognize
  186.     fname    <EXIT>        ; --    R: nest-sys --
  187.     docode            ; CORE
  188.     poprpto    ip        ; IP := @RP++
  189.     next
  190.  
  191.     zname    <DOKWORDLIST>    ; -- a-addr
  192.                 ; Implementation detail, Execution engine for wordlists declared in the kernel
  193.     lea    edx,cell[wp]    ; pointer to data space where list end is stored
  194.     sub    edx,dp        ; convert abs address to data address
  195.     push    edx        ; push
  196.     next
  197.  
  198.     zname    <DOWORDLIST>    ; -- a-addr
  199.                 ; Implementation detail, Execution engine for wordlists created by user
  200.     lea    edx,cell[wp]    ; get self-pointer of a Wordlist
  201.     add    edx,cp        ; convert from user dict address to abs address
  202.     sub    edx,dp        ; convert abs address to data address
  203.     push    eax        ; push
  204.     next
  205.  
  206.     fname    <EXECUTE>    ; i*x xt -- j*x
  207.     docode            ; CORE
  208.     pop    wp
  209.     innext
  210.  
  211.     zname    <DOLIT>        ; -- x
  212.     docode            ; Implementation detail
  213.     lodsd            ; advance instruction pointer fetching literal value
  214.     push    eax        ; push literal
  215.     next
  216.  
  217.     zname    <DODLIT>    ; -- 
  218.     docode            ; Implementation detail
  219.     lodsd            ; advance instruction pointer fetching literal value
  220.     mov    edx,eax        ; save hi 32 bits
  221.     lodsd            ; advance instruction pointer fetching literal value
  222.     push    eax        ; push literal loword
  223.     push    edx        ; push literal hiword
  224.     next
  225.  
  226.     zname    <DOIF>        ; flag -- 
  227.     docode            ;Implementation detail, also is UNTIL
  228.     pop    eax
  229.     and    eax,eax        ; test flag
  230.     je    doelse        ; if zero, we branch
  231.     add    ip,cell        ; wasn't zero, we advance IP
  232.     next
  233.  
  234.     zname    <DOELSE>    ; --
  235.     docode            ; Implementation detail, also is AGAIN, REPEAT
  236. doelse:    mov    wp,[ip]
  237.     dereftok
  238.     mov    ip,wp
  239.     next
  240.  
  241.     zname    <DOUNTIL>    ; flag --
  242.     docode            ; Implementation detail
  243.     pop    eax
  244.     and    eax,eax        ; test flag
  245.     je    doelse        ; if zero, we branch
  246.     add    ip,cell        ; was zero, we advance IP
  247.     next
  248.  
  249.     zname    <DOUNTILNOT>    ; flag --
  250.     docode            ; Implementation detail, used this once, not sure why ..
  251.     pop    eax
  252.     and    eax,eax        ; test flag
  253.     jne    doelse        ; if nonzero, we branch
  254.     add    ip,cell        ; was zero, we advance IP
  255.     next
  256.  
  257.     zname    <DODO>        ; u1 u2 --
  258.     docode            ; Implementation detail
  259. dodo:    lodsd            ; WP := exit address
  260.     dereftok
  261.     pushrp    wp        ; save exit address on return stack
  262.     pop    eax        ; inner loop index
  263.     pop    edx        ; outer loop index
  264.     add    edx,80000000H    ; add overflow limit to outer
  265.     sub    eax,edx        ; massage inner
  266.     pushrp    edx        ; push massaged outer to RStack
  267.     pushrp    eax        ; push massaged inner to RStack
  268.     next
  269.  
  270.     zname    <DOQDO>        ; u1 u2 --
  271.     docode            ; Implementation detail
  272.     mov    edx,[esp]    ; copy of TOS
  273.     cmp    cell[esp],edx    ; compare to other index
  274.     jne    dodo        ; they are different: go ahead and DO
  275.     add    esp,2*cell    ; same: clear stack
  276.     lodsd            ; WP := @IP++
  277.     dereftok
  278.     mov    ip,wp        ; IP := WP i.e., exit address compiled in cell ahead of DOQDO token
  279.     next            ; onwards
  280.  
  281.     zname    <DOLOOP>    ; --
  282.     docode            ; Implementation detail
  283. doloop:    poprpto    eax        ; massaged inner index
  284.     inc    eax        ; increment
  285.     jo    doloop1        ; overflow flag, we're done
  286.     pushrp    eax        ; not done, return incremented count
  287.     lodsd            ; WP := @IP++, i.e., WP is loaded with branchback address
  288.     dereftok
  289.     mov    ip,wp        ; IP := branch back
  290.     next            ; continue
  291. doloop1:
  292.     add    rp,2*cell    ; clear return stack
  293.     add    ip,cell        ; branch past loopback address
  294.     next            ; onwards and outwards
  295.     
  296.     zname    <DOPLUSLOOP>    ; n1 --
  297.     docode            ; Implementation detail
  298.     poprpto    eax        ; massaged inner index
  299.     pop    edx        ; increment
  300.     add    eax,edx        ; add increment to index
  301.     jo    doloop1        ; overflow flag, we're done, we can re-use the above code
  302.     pushrp    eax        ; not done, return incremented count
  303.     lodsd            ; WP := @IP++, i.e., WP is loaded with branchback address
  304.     dereftok
  305.     mov    ip,wp        ; IP := branch back
  306.     next            ; continue
  307.  
  308. ; Strings for S" and TYPE must reside in data space. In the dictionary they are recorded /DOSQUOTE/D-ADDR/
  309.     zname    <DOSQUOTE>    ; -- c-addr u
  310.     docode            ; Implementation detail
  311.     lodsd            ; count address in ax
  312.     xor    edx,edx        ; clear dx
  313.     mov    dx,[eax][dp]    ; get count
  314.     add    eax,tchar    ; form data address of string
  315.     push    eax        ; push c-addr
  316.     push    edx        ; push u
  317.     next
  318.  
  319.     zname    <DODOTQUOTE>    ; --
  320.     docode            ; Implementation detail
  321.     lodsd            ; count address in wp (EAX)
  322.     xor    edx,edx        ; clear dx
  323.     mov    dx,[eax+dp]    ; get count
  324.     add    eax,tchar    ; form data address of string
  325.     push    eax        ; push c-addr
  326.     push    edx        ; push u
  327.     jmp    ftype        ; goto type
  328.  
  329.     zname    <DOKDOTQUOTE>    ; --        Print strings stored in the kernel exe data section
  330.     docode            ; Implementation detail.
  331.     lodsd            ; count address in wp (EAX)
  332.     sub    eax,dp        ; convert to data-relative address
  333.     xor    edx,edx        ; clear dx
  334.     mov    dx,[eax+dp]    ; get count
  335.     add    eax,tchar    ; form data address of string
  336.     push    eax        ; push c-addr
  337.     push    edx        ; push u
  338.     jmp    ftype        ; goto typ
  339.     
  340. ;--( Stack Operators )
  341.  
  342.     fname    <DROP>        ; x --
  343.     docode            ; CORE
  344.     pop    eax
  345.     next
  346.  
  347.     fnamemanque    <2DROP>    ; x1 x2 --
  348. fw_TWO_DROP:
  349.     docode            ; CORE
  350.     pop    eax
  351.     pop    eax
  352.     next
  353.  
  354.     fnamemanque    <?DUP>        ; x -- x x | 0
  355. fw_QDUP:
  356.     docode                ; CORE
  357.     cmp    DWORD PTR [esp],0
  358.     jne    dupe
  359.     next
  360.  
  361.     fname    <DUP>        ; x -- x x
  362.     docode            ; CORE
  363. dupe:    push    [esp]
  364.     next
  365.  
  366.     fnamemanque    <2DUP>    ; x1 x2 -- x1 x2 x1 x2
  367. fw_TWO_DUP:
  368.     docode            ; CORE
  369.     push    cell[esp]
  370.     push    cell[esp]
  371.     next
  372.  
  373.     fname    <OVER>        ; x1 x2 -- x1 x2 x1
  374.     dd    over        ; CORE
  375. over:    push    cell[esp]
  376.     next
  377.  
  378.     fnamemanque    <2OVER>    ; x1 x2 x3 x4-- x1 x2 x3 x4 x1 x2
  379. fw_TWO_OVER:
  380.     docode            ; CORE
  381.     push    3*cell[esp]
  382.     push    3*cell[esp]
  383.     next
  384.  
  385.     fname    <ROT>        ; x1 x2 x3 -- x2 x3 x1
  386.     docode            ; CORE
  387.     pop    eax
  388.     pop    ecx
  389.     pop    edx
  390.     push    ecx
  391.     push    eax
  392.     push    edx
  393.     next
  394.  
  395.     nnamemanque    <-ROT>    ; x1 x2 x3 -- x3 x1 x2
  396. fw_NEGROT:            ; Not in Standard
  397.     docode
  398.     pop    eax
  399.     pop    ecx
  400.     pop    edx
  401.     push    eax
  402.     push    edx
  403.     push    ecx
  404.     next
  405.  
  406.     fname    <SWAP>        ; x1 x2 -- x2 x1
  407.     docode            ; CORE
  408.     pop    eax
  409.     pop    edx
  410.     push    eax
  411.     push    edx
  412.     next
  413.  
  414.     fnamemanque    <2SWAP>    ; x1 x2 x3 x4-- x3 x4 x1 x2
  415. fw_TWO_SWAP:            ; CORE
  416.     docode
  417.     mov    eax,3*cell[esp]
  418.     mov    edx,cell[esp]
  419.     mov    3*cell[esp],edx
  420.     mov    cell[esp],eax
  421.     mov    eax,2*cell[esp]
  422.     mov    edx,[esp]
  423.     mov    2*cell[esp],edx
  424.     mov    [esp],eax
  425.     next
  426.  
  427. ; Can't use our name header macros with this one!
  428.     linkme    flinkptr
  429.     countcell    2
  430.     db    '>',0,'R',0    ; x --    R: -- x
  431.     align    4        ; CORE
  432. fw_TO_R:
  433.     docode
  434.     sub    rp,cell
  435.     pop    [rp]
  436.     next
  437.  
  438. ; Can't use our name header macros with this one!
  439.     linkme    flinkptr
  440.     countcell    2
  441.     db    'R',0,'>',0    ; -- x    R: x --
  442.     align    4        ; CORE
  443. fw_R_FROM:
  444.     docode
  445.     push    [rp]
  446.     add    rp,cell
  447.     next
  448.  
  449.     fnamemanque    <R@>    ; -- x    R: x -- x
  450. fw_R_FETCH:            ; CORE
  451.     docode        
  452.     push    DWORD PTR [rp]
  453.     next
  454.  
  455. ; Can't use our name header macros with this one!
  456.     linkme    nlinkptr
  457.     countcell    3
  458.     db    'R',0,'P',0,'!',0    ; addr --
  459.     align    4            ; Implementation
  460. fw_RP_STORE:
  461.     docode
  462.     pop    rp
  463.     next
  464.  
  465.     nnamemanque    <RP@>
  466. fw_RP_FETCH:                ; -- addr
  467.     docode                ; Implementation
  468.     push    rp
  469.     next
  470.  
  471.     fname    <TUCK>        ; x1 x2 -- x2 x1 x2
  472.     docode            ; CORE EXT
  473.     pop    eax
  474.     pop    edx
  475.     push    eax
  476.     push    edx
  477.     push    eax
  478.     next
  479.  
  480.     fname    <NIP>        ; x1 x2 -- x2
  481.     docode            ; CORE EXT
  482.     pop    eax
  483.     pop    edx
  484.     push    eax
  485.     next
  486.  
  487.     fname    <PICK>        ; xu .. x1 x0 u -- xu .. x1 x0 xu
  488.     docode            ; CORE EXT
  489.     pop    eax
  490.     push    [esp][eax*cell]
  491.     next
  492.     
  493.     fname    <DEPTH>        ; i*x -- i*x i
  494.     ctok    NEST        ; CORE
  495.     ctok    SP_FETCH    ; -- @esp
  496.     ctok    SP0
  497.     ctok    FETCH        ; -- @esp @orig-esp
  498.     ctok    SWAP
  499.     ctok    MINUS        ; -- diff
  500.     literal    1
  501.     ctok    CELLS        ; -- diff cell-size
  502.     ctok    SLASH        ; -- cells-diff
  503.     ctok    UNNEST
  504.  
  505. ; Get current data stack pointer value, an absolute address
  506.     nnamemanque    <SP@>    ; -- abs-addr
  507. fw_SP_FETCH:            ; Not in Standard
  508.     docode
  509.     push    esp
  510.     next
  511.  
  512. ; Can't use our name header macros with this one!
  513.     linkme    nlinkptr
  514.     countcell    3
  515.     db    'S',0,'P',0,'!'    ; abs-addr --        Set data stack pointer value, an absolute address
  516.     align    4
  517. fw_SP_STORE:            ; Not in Standard
  518.     docode
  519.     pop    esp
  520.     next
  521.  
  522. ; Get saved-at-boot data stack pointer value
  523.     nname    <SP0>        ; -- a-addr
  524.     ctok    DOCONST        ; Not in Standard
  525.     dd    ntConESP
  526.  
  527. ;--( Data Movement )
  528.  
  529. ; Can't use our name header macros with this one!
  530.     linkme    flinkptr
  531.     countcell    1
  532.     db    '!',0        ; x a-addr --
  533.     align    4        ; CORE
  534. fw_STORE:
  535.     docode
  536.     pop    eax
  537.     pop    [eax][dp]
  538.     next
  539.  
  540. ; Can't use our name header macros with this one!
  541.     linkme    flinkptr
  542.     countcell    2
  543.     db    '+',0,'!',0    ; x a-addr --
  544.     align    4        ; CORE
  545. fw_PL_STORE:
  546.     docode
  547.     pop    eax
  548.     pop    edx
  549.     add    [eax][dp],edx
  550.     next
  551.  
  552.     fnamemanque    <@>    ; a-addr -- x
  553. fw_FETCH:
  554.     docode            ; CORE
  555.     pop    eax
  556.     push    [eax][dp]
  557.     next
  558.  
  559. ; Can't use our name header macros with this one!
  560.     linkme    flinkptr
  561.     countcell    2
  562.     db    'C',0,'!',0    ; c c-addr --
  563.     align    4        ; CORE
  564. fw_C_STORE:
  565.     docode
  566.     pop    eax
  567.     pop    edx
  568.     mov    [eax][dp],dx
  569.     next
  570.  
  571.     fnamemanque    <C@>    ; c-addr -- c
  572. fw_C_FETCH:
  573.     docode            ; CORE
  574.     mov    eax,[esp]
  575.     mov    dx,[eax][dp]
  576.     movzx    eax,dx
  577.     mov    [esp],eax    
  578.     next
  579.  
  580. ; Can't use our name header macros with this one!
  581.     linkme    nlinkptr
  582.     countcell    2
  583.     db    'B',0,'!',0    ; byte c-addr --
  584.     align    4        ; Not in Standard
  585. fw_B_STORE:
  586.     docode
  587.     pop    eax
  588.     pop    edx
  589.     mov    [eax][dp],dl
  590.     next
  591.  
  592.     nnamemanque    <B@>    ; c-addr -- byte
  593. fw_B_FETCH:
  594.     docode            ; Not in Standard
  595.     mov    eax,[esp]
  596.     mov    dl,[eax][dp]
  597.     movzx    eax,dl    
  598.     mov    [esp],eax    
  599.     next
  600.  
  601. ; Can't use our name header macros with this one!
  602.     linkme    flinkptr
  603.     countcell    2
  604.     db    '2',0,'!',0    ; x1 x2 a-addr --
  605.     align    4        ; CORE
  606. fw_TWO_STORE:
  607.     docode
  608.     pop    eax
  609.     pop    [eax][dp]
  610.     pop    [eax+cell][dp]
  611.     next
  612.  
  613.     fnamemanque    <2@>    ; a-addr -- x1 x2
  614. fw_TWO_FETCH:
  615.     docode            ; CORE
  616.     pop    eax
  617.     push    [eax+cell][dp]
  618.     push    [eax][dp]
  619.     next
  620.  
  621. ; Can't use our name header macros with this one!
  622.     linkme    flinkptr
  623.     countcell    1
  624.     db    ',',0        ; x --
  625.     align    4        ; CORE
  626. fw_COMMA:
  627.     docode
  628.     mov    eax,[dp+datap]    ; get data space pointer
  629.     pop    [eax][dp]    ; pop to that offset in data space
  630.     add    DWORD PTR datap[dp],cell    ; post-increment pointer
  631.     next
  632.  
  633. ; Can't use our name header macros with this one!
  634.     linkme    flinkptr
  635.     countcell    2
  636.     db    'C',0,',',0    ; char --
  637.     align    4        ; CORE
  638. fw_CCOMMA:
  639.     docode
  640.     mov    eax,[dp+datap]            ; get data space pointer
  641.     pop    edx                ; get char
  642.     mov    [eax][dp],dx            ; pop char to that offset in data space
  643.     add    DWORD PTR datap[dp],tchar    ; post-increment pointer
  644.     next
  645.  
  646.     fname    <MOVE>        ; addr1 addr2 u --
  647.     docode
  648.     pop    ecx        ; count
  649.     pop    eax        ; destination
  650.     pop    edx        ; source
  651.     and    ecx,ecx        ; is count zero?
  652.     je    move2        ; if zero count, exit
  653.     cld            ; now set to move string upwards
  654.     cmp    eax,edx        ; destination - source
  655.     jb    move1        ; jump if destination < source, continue further on
  656.     add    eax,ecx
  657.     dec    eax
  658.     add    edx,ecx
  659.     dec    edx
  660.     std            ; destination >= source, copy downwards
  661. move1:    add    eax,dp        ; absolute destination
  662.     add    edx,dp        ; absolute source
  663.     push    edi        ; save edi
  664.     push    esi        ; save esi
  665.     push    edx        ; load source
  666.     pop    esi
  667.     push    eax        ; load dest
  668.     pop    edi
  669.     push    ds        ; same seg ..
  670.     pop    es        ; .. for source and dest
  671.     rep    movsb        ; copy address units ... this can be optimized later
  672.     pop    esi        ; restore esi
  673.     pop    edi        ; restore edi
  674.     cld            ; !!!***!!! VERY IMPORTANT because NEST depends on it !!!***!!!
  675. move2:    next
  676.  
  677. ;--( Comparisons )
  678.  
  679. ; Can't use our name header macros with this one!
  680.     linkme    flinkptr
  681.     countcell    2
  682.     db    '0',0,'<',0    ; x -- flag
  683.     align    4        ; CORE
  684. fw_ZEROLT:
  685.     docode
  686.     mov    eax,[esp]
  687.     shl    eax,1
  688.     sbb    edx,edx
  689.     mov    [esp],edx
  690.     next
  691.  
  692.     fnamemanque    <0=>    ; x -- flag
  693. fw_ZEROEQ:
  694.     docode            ; CORE
  695.     mov    eax,[esp]
  696.     and    eax,eax
  697.     je    zeroeq1
  698.     mov    DWORD PTR [esp],FALSE
  699.     next
  700. zeroeq1:
  701.     mov    DWORD PTR [esp],TRUE
  702.     next
  703.  
  704. ; Can't use our name header macros with this one!
  705.     linkme    flinkptr
  706.     countcell    3
  707.     db    '0',0,'<',0,'>',0    ; x -- flag
  708.     align    4            ; CORE EXT
  709. fw_ZERONE:
  710.     docode
  711.     mov    eax,[esp]
  712.     and    eax,eax
  713.     jne    zeroeq1            ; reuse code above
  714.     mov    DWORD PTR [esp],FALSE
  715.     next
  716.  
  717. ; Can't use our name header macros with this one!
  718.     linkme    flinkptr
  719.     countcell    2
  720.     db    '0',0,'>',0    ; x -- flag
  721.     align    4        ; CORE EXT
  722. fw_ZEROGT:
  723.     ctok    NEST
  724.     ctok    DUP        ; -- x x
  725.     ctok    ZEROLT        ; -- x flag
  726.     ctok    SWAP        ; -- flag x
  727.     ctok    ZEROEQ        ; -- flag1 flag2
  728.     ctok    OR        ; -- flag
  729.     ctok    ZEROEQ        ; -- flag'
  730.     ctok    UNNEST
  731.  
  732. ; Can't use our name header macros with this one!
  733.     linkme    flinkptr
  734.     countcell    1
  735.     db    '<',0        ; n1 n2 -- flag
  736.     align    4        ; CORE
  737. fw_LESS:
  738.     docode
  739.     pop    eax
  740.     mov    edx,[esp]
  741.     cmp    edx,eax
  742.     jl    less1
  743.     mov    DWORD PTR [esp],FALSE
  744.     next
  745. less1:    mov    DWORD PTR [esp],TRUE
  746.     next
  747.  
  748. ; Can't use our name header macros with this one!
  749.     linkme    flinkptr
  750.     countcell    2
  751.     db    'U',0,'<',0    ; u1 u2 -- flag
  752.     align    4        ; CORE
  753. fw_U_LESS:
  754.     docode
  755.     pop    eax
  756.     mov    edx,[esp]
  757.     cmp    edx,eax
  758.     jb    less1        ; we can re-use code from above
  759.     mov    DWORD PTR [esp],FALSE
  760.     next
  761.  
  762. ; Can't use our name header macros with this one!
  763.     linkme    nlinkptr
  764.     countcell    3
  765.     db    'U',0,'D',0,'<',0    ; ud1 ud2 -- flag
  766.     align    4        ; Not in standard
  767. fw_UD_LESS:
  768.     docode
  769.     pop    edx        ; ud2h
  770.     pop    eax        ; ud2l
  771.     pop    ecx        ; ud1h
  772.     cmp    edx,ecx        ; ud2h
  773.     ja    udless        ; if ud2h > ud1h, TRUE
  774.     jb    nudless        ; if ud2h < ud1h, FALSE
  775.     cmp    eax,[esp]    ; they were equal, try low half
  776.     ja    udless        ; now if ud2l > ud1l, TRUE
  777. nudless:            ; ud2l =< ud1l, FALSE
  778.     mov    DWORD PTR [esp],FALSE
  779.     next
  780. udless:    mov    DWORD PTR [esp],TRUE
  781.     next
  782.  
  783.  
  784. ; Can't use our name header macros with this one!
  785.     linkme    flinkptr
  786.     countcell    2
  787.     db    'D',0,'=',0        ; xd1 xd2 -- flag
  788.     align    4        ; DOUBLE
  789. fw_DEQUAL:
  790.     docode
  791.     pop    edx            ; d2h
  792.     pop    eax            ; d2l
  793.     pop    ecx            ; d1h
  794.     cmp    edx,ecx            ; d2h == d1h?
  795.     jne    dnequal            ; no
  796.     cmp    eax,[esp]        ; yes, try lower
  797.     jne    dnequal            ; d2l != d1l
  798.     mov    DWORD PTR [esp],TRUE    ; d2l == d1l
  799.     next
  800. dnequal:
  801.     mov    DWORD PTR [esp],FALSE
  802.     next
  803.  
  804. ; Can't use our name header macros with this one!
  805.     linkme    flinkptr
  806.     countcell    1
  807.     db    '=',0        ; x1 x2 -- flag
  808.     align    4        ; CORE
  809. fw_EQUAL:
  810.     docode
  811.     pop    eax
  812.     mov    edx,[esp]
  813.     cmp    eax,edx
  814.     je    equal1
  815.     mov    DWORD PTR [esp],FALSE
  816.     next
  817. equal1:    mov    DWORD PTR [esp],TRUE
  818.     next
  819.  
  820. ; Can't use our name header macros with this one!
  821.     linkme    flinkptr
  822.     countcell    2
  823.     db    '<',0,'>',0    ; x1 x2 -- flag
  824.     align    4        ; CORE EXT
  825. fw_NEQUAL:
  826.     docode
  827.     pop    eax
  828.     mov    edx,[esp]
  829.     cmp    eax,edx
  830.     jne    equal1            ; re-using above code
  831.     mov    DWORD PTR [esp],FALSE
  832.     next
  833.  
  834.  
  835. ; Can't use our name header macros with this one!
  836.     linkme    flinkptr
  837.     countcell    1
  838.     db    '>',0        ; n1 n2 -- flag
  839.     align    4        ; CORE
  840. fw_GREATER:
  841.     docode
  842.     pop    eax
  843.     mov    edx,[esp]
  844.     cmp    edx,eax
  845.     ja    greater1
  846.     mov    DWORD PTR [esp],FALSE
  847.     next
  848. greater1:
  849.     mov    DWORD PTR [esp],TRUE
  850.     next
  851.  
  852.     fname    <MAX>        ; n1 n2 -- n3
  853.     docode            ; CORE
  854.     pop    eax
  855.     pop    edx
  856.     cmp    eax,edx
  857.     jl    f_max1
  858.     push    eax
  859.     next
  860. f_max1:    push    edx
  861.     next
  862.  
  863.     fname    <MIN>        ; n1 n2 -- n3
  864.     docode            ; CORE
  865.     pop    edx
  866.     pop    eax
  867.     cmp    eax,edx
  868.     ja    f_max1        ; reuse code from above
  869.     push    eax
  870.     next
  871.  
  872.     fname    <WITHIN>    ; n|u1 n|u2 n|u3 -- flag
  873.     ctok    NEST        ; CORE EXT
  874.     ctok    OVER
  875.     ctok    MINUS        ; -- n1 n2 diffn3n2
  876.     ctok    TO_R        ; -- n1 n2            R: -- diffn3n2
  877.     ctok    MINUS        ; -- diffn1n2            R: -- diffn3n2
  878.     ctok    R_FROM        ; -- diffn1n2 diffn3n2        R: --
  879.     ctok    U_LESS        ; -- flag
  880.     ctok    UNNEST
  881.  
  882. ;--( Integer Math )
  883.  
  884.     fnamemanque    <1+>    ; n|u1 -- n|u2
  885. fw_ONE_PLUS:
  886.     docode
  887.     add    DWORD PTR [esp],1
  888.     next
  889.  
  890.     fnamemanque    <1->    ; n|u1 -- n|u2
  891. fw_ONE_MINUS:
  892.     docode
  893.     sub    DWORD PTR [esp],1
  894.     next
  895.  
  896.     fname    <ABS>        ; n -- u
  897.     ctok    NEST        ; CORE
  898.     ctok    DUP
  899.     ctok    ZEROLT        ; -- n flag
  900.     compif    abs1
  901.     ctok    NEGATE
  902. abs1:    ctok    UNNEST        ; -- _n_
  903.  
  904.     fname    <DABS>        ; d -- ud
  905.     ctok    NEST        ; DOUBLE
  906.     ctok    DUP
  907.     ctok    ZEROLT        ; -- d flag
  908.     compif    dabs1
  909.     ctok    DNEGATE
  910. dabs1:    ctok    UNNEST        ; -- _d_
  911.  
  912. ; Can't use our name header macros with this one!
  913.     linkme    flinkptr
  914.     countcell    3
  915.     db    'S',0,'>',0,'D',0    ; n1 -- d1
  916.     align    4            ; CORE
  917. fw_S_TO_D:
  918.     docode
  919.     mov    eax,[esp]
  920.     cdq
  921.     push    edx
  922.     next
  923.  
  924.     fname    <NEGATE>    ; n1 -- n2
  925.     docode            ; CORE
  926.     mov    eax,[esp]
  927.     neg    eax
  928.     mov    [esp],eax
  929.     next
  930.  
  931.     fname    <DNEGATE>    ; d1 -- d2
  932.     docode            ; DOUBLE
  933.     xor    eax,eax
  934.     xor    edx,edx
  935.     sub    eax,cell[esp]
  936.     sbb    edx,[esp]
  937.     mov    cell[esp],eax
  938.     mov    [esp],edx
  939.     next    
  940.  
  941.     fnamemanque    <+>    ; n|u1 n|u2 -- n|u3
  942. fw_PLUS:            ; CORE
  943.     docode
  944.     pop    eax
  945.     add    [esp],eax
  946.     next
  947.  
  948.     fnamemanque    <D+>    ; ud|d1 ud|d2 -- ud|d3
  949. fw_D_PLUS:            ; DOUBLE
  950.     docode
  951.     pop    edx            ; d2h
  952.     pop    eax            ; d2l
  953.     add    cell[esp],eax        ; d1l+d2l
  954.     adc    [esp],edx        ; d1h+d2h+carry
  955.     next
  956.  
  957.     fnamemanque    <->    ; n|u1 n|u2 -- n|u3
  958. fw_MINUS:            ; CORE
  959.     docode
  960.     pop    eax
  961.     sub    [esp],eax
  962.     next
  963.  
  964.     fnamemanque    <D->    ; ud|d1 ud|d2 -- ud|d3
  965. fw_D_MINUS:            ; DOUBLE
  966.     docode
  967.     pop    edx        ; d2h
  968.     pop    eax        ; d2l
  969.     sub    cell[esp],eax    ; d1l-d2l
  970.     sbb    [esp],edx    ; d1h-d2h-borrow
  971.     next
  972.  
  973.     fnamemanque    <*>    ; n|u1 n|u2 -- n|u3
  974. fw_STAR:            ; CORE
  975.     docode    
  976.     pop    eax
  977.     imul    DWORD PTR[esp]
  978.     mov    [esp],eax
  979.     next
  980.  
  981.     fnamemanque    </>    ; n1 n2 -- n3
  982. fw_SLASH:            ; CORE
  983.     docode
  984.     pop    ecx        ; n2
  985.     pop    eax        ; n1
  986.     xor    edx,edx    ; high order for div
  987.     idiv    ecx        ; n1 / n2
  988.     push    eax        ; quotient
  989.     next            ; -- n3
  990.  
  991.     fnamemanque    </MOD>    ; n1 n2 -- n3 n4
  992. fw_SLMOD:            ; CORE
  993.     docode
  994.     pop    ecx        ; n2
  995.     pop    eax        ; n1
  996.     xor    edx,edx        ; high order for div
  997.     idiv    ecx        ; n1 / n2
  998.     push    edx        ; remainder
  999.     push    eax        ; quotient
  1000.     next            ; -- n3 n4
  1001.  
  1002.     fname    <MOD>        ; n1 n2 -- n3
  1003.     ctok    NEST
  1004.     ctok    SLMOD
  1005.     ctok    DROP
  1006.     ctok    UNNEST
  1007.  
  1008.     fnamemanque    <*/>    ; n1 n2 n3 -- n4
  1009. fw_STARSL:            ; CORE
  1010.     docode
  1011.     pop    ecx        ; n3
  1012.     pop    edx        ; n2
  1013.     pop    eax        ; n1
  1014.     imul    edx        ; n1 * n2
  1015.     idiv    ecx        ; intermediate / n3
  1016.     push    eax        ; quotient
  1017.     next            ; -- n4
  1018.  
  1019.     fnamemanque    <*/MOD>    ; n1 n2 n3 -- n4 n5
  1020. fw_STARSLMOD:            ; CORE
  1021.     docode
  1022.     pop    ecx        ; n3
  1023.     pop    edx        ; n2
  1024.     pop    eax        ; n1
  1025.     imul    edx        ; n1 * n2        
  1026.     idiv    ecx        ; intermediate / n3
  1027.     push    edx        ; remainder
  1028.     push    eax        ; quotient
  1029.     next            ; -- n4 n5
  1030.  
  1031.          nnamemanque    <DUM/MOD>    ; d1 n1 -- n2 d2
  1032. fw_DUMSLMOD:                ; not in Standard
  1033.     ctok    NEST
  1034.     ctok    TO_R            ; -- d1l d1h        R: -- n1
  1035.     literal    0            ; -- d1l d1h 0        R: -- n1
  1036.     ctok    R_FETCH            ; -- d1l d1h 0 n1    R: -- n1
  1037.     ctok    UMSLMOD            ; -- d1l r1 q1        R: -- n1
  1038.     ctok    R_FROM            ; -- d1l r1 q1 n1    R: --
  1039.     ctok    SWAP            ; -- d1l r1 n1 q1    R: --
  1040.     ctok    TO_R            ; -- d1l r1 n1        R: -- d2h
  1041.     ctok    UMSLMOD            ; -- r2 q2        R: -- d2h
  1042.     ctok    R_FROM            ; -- n2 d2
  1043.     ctok    UNNEST            ; -- n2 d2
  1044.  
  1045.     fnamemanque    <FM/MOD>    ; d1 n1 -- n2 n3
  1046. fw_FMSLMOD:                ; CORE
  1047.     ctok    NEST
  1048.     ctok    DUP            ; -- d1    n1
  1049.     ctok    TO_R            ; -- d1    n1        R: -- n1
  1050.     ctok    ZEROLT            ; -- d1    flag        R: -- n1
  1051.     compif    fmslmod1
  1052.     ctok    DNEGATE
  1053. fmslmod1:
  1054.     ctok    S_TO_D            ; -- d1l d1hl d1hh        R: -- n1
  1055.     ctok    R_FETCH            ; -- d1l d1hl d1hh n1        R: -- n1
  1056.     ctok    ABS            ; -- d1l d1hl d1hh _n1_        R: -- n1
  1057.     ctok    AND            ; -- d1l d1hl d1hh _n1_        R: -- n1
  1058.     ctok    PLUS            ; -- d1l intermed        R: -- n1
  1059.     ctok    R_FETCH            ; -- d1l intermed n1        R: -- n1
  1060.     ctok    ABS            ; -- d1l intermed _n1_        R: -- n1
  1061.     ctok    UMSLMOD            ; -- n2' n3            R: -- n1
  1062.     ctok    SWAP            ; -- n3 n2'            R: -- n1
  1063.     ctok    R_FROM            ; -- n3 n2' n1            R: --
  1064.     ctok    ZEROLT            ; -- n3 n2' flag
  1065.     compif    fmslmod2
  1066.     ctok    NEGATE            ; -- n3 n2
  1067. fmslmod2:
  1068.     ctok    SWAP            ; -- n2 n3
  1069.     ctok    UNNEST
  1070.  
  1071.     fnamemanque    <SM/REM>    ; d1 n1 -- n2 n3
  1072. fw_SMSLREM:                ; CORE
  1073.     docode
  1074.     pop    ecx        ; u1
  1075.     pop    edx        ; udh
  1076.     pop    eax        ; udl
  1077.     idiv    ecx
  1078.     push    edx        ; remainder
  1079.     push    eax        ; quotient
  1080.     next            ; -- u2 u3
  1081.  
  1082.     fnamemanque    <UM*>    ; u1 u2 -- ud
  1083. fw_UMSTAR:            ; CORE
  1084.     docode
  1085.     mov    eax,cell[esp]    ; u1
  1086.     mul    DWORD PTR [esp]    ; u1*u2
  1087.     mov    cell[esp],eax    ; udl
  1088.     mov    [esp],edx    ; udh
  1089.     next            ; -- ud
  1090.  
  1091.     fnamemanque    <UM/MOD>    ; ud u1 -- u2 u3)
  1092. fw_UMSLMOD:                ; CORE
  1093.     docode
  1094.     pop    ecx        ; u1
  1095.     pop    edx        ; udh
  1096.     pop    eax        ; udl
  1097.     div    ecx
  1098.     push    edx        ; remainder
  1099.     push    eax        ; quotient
  1100.     next            ; -- u2 u3
  1101.  
  1102.     fnamemanque    <M*>    ; n1 n2 -- d
  1103. fw_MSTAR:            ; CORE
  1104.     docode
  1105.     mov    eax,cell[esp]    ; n1
  1106.     imul    DWORD PTR [esp]    ; n1*n2
  1107.     mov    cell[esp],eax    ; dl
  1108.     mov    [esp],edx    ; dh
  1109.     next            ; -- ud
  1110.  
  1111.     nnamemanque    <UD*U>    ; ud1 u1 -- ud2
  1112. fw_UDSTARU:            ; not in standard
  1113.     docode
  1114.     pop    ecx        ; u1
  1115.     pop    eax        ; ud1h
  1116.     mul    ecx        ; produce extended ud2h
  1117.     mov    edx,ecx        ; discard upper dword of ud2he, move multiplier into edx
  1118.     mov    ecx,eax        ; save lower portion of ud2he in ecx
  1119.     pop    eax        ; ud1l
  1120.     mul    edx        ; ud2l in eax
  1121.     push    eax        ; return ud2l
  1122.     add    edx,ecx        ; form ud2h
  1123.     push    edx        ; return ud2h
  1124.     next            ; -- ud2
  1125.  
  1126. ;--( Bit Operators )
  1127.  
  1128.     fname    <TRUE>        ; -- flag
  1129.     ctok    DOCONST        ; CORE EXT
  1130.     dd    TRUE
  1131.  
  1132.     fname    <FALSE>        ; -- flag
  1133.     ctok    DOCONST        ; CORE EXT
  1134.     dd    FALSE
  1135.  
  1136.     fname    <AND>        ; x1 x2 -- x3
  1137.     docode            ; CORE
  1138.     pop    eax
  1139.     and    [esp],eax
  1140.     next
  1141.  
  1142.     fname    <OR>        ; x1 x2 -- x3
  1143.     docode            ; CORE
  1144.     pop    eax
  1145.     or    [esp],eax
  1146.     next
  1147.  
  1148.     fname    <XOR>        ; x1 x2 -- x3
  1149.     docode            ; CORE
  1150.     pop    eax
  1151.     xor    [esp],eax
  1152.     next
  1153.  
  1154.     fname    <INVERT>    ; x1 -- x2
  1155.     docode            ; CORE
  1156.     mov    eax,[esp]
  1157.     not    eax
  1158.     mov    [esp],eax
  1159.     next
  1160.  
  1161.     fnamemanque    <2*>    ; x1 -- x2
  1162. fw_TWO_STAR:            ; CORE
  1163.     docode
  1164.     mov    eax,[esp]
  1165.     shl    eax,1
  1166.     mov    [esp],eax
  1167.     next
  1168.  
  1169.     fnamemanque    <2/>    ; x1 -- x2
  1170. fw_TWO_SLASH:            ; CORE
  1171.     docode
  1172.     mov    eax,[esp]
  1173.     shr    eax,1
  1174.     mov    [esp],eax
  1175.     next
  1176.  
  1177.     fname    <LSHIFT>    ; x1 u -- x2
  1178.     docode            ; CORE
  1179.     pop    ecx
  1180.     mov    eax,[esp]
  1181.     shl    eax,cl
  1182.     mov    [esp],eax
  1183.     next
  1184.  
  1185.     fname    <RSHIFT>    ; x1 u -- x2
  1186.     docode            ; CORE
  1187.     pop    ecx
  1188.     mov    eax,[esp]
  1189.     shr    eax,cl
  1190.     mov    [esp],eax
  1191.     next
  1192.  
  1193. ;--( Characters )
  1194.  
  1195.     fname    <BL>        ; -- char
  1196.     ctok    DOCONST        ; CORE
  1197.     dd    20H
  1198.  
  1199.     fname    <CHAR>        ; -- char
  1200.     ctok    NEST        ; CORE
  1201.     ctok    BL
  1202.     ctok    WORD
  1203.     ctok    CHAR_PLUS
  1204.     ctok    C_FETCH
  1205.     ctok    UNNEST
  1206.  
  1207.     finamemanque    <[CHAR]>    ; --    Execution: -- char
  1208. fw_BRACHETCHAR:
  1209.     ctok    NEST            ; CORE
  1210.     ctok    CHAR
  1211.     ctok    LITERAL
  1212.     ctok    UNNEST
  1213.  
  1214.     fname    <SPACE>        ; --
  1215.     ctok    NEST        ; CORE
  1216.     ctok    BL
  1217.     ctok    EMIT
  1218.     ctok    UNNEST
  1219.  
  1220.     fname    <SPACES>    ; n --
  1221.     ctok    NEST        ; CORE
  1222.     literal    0
  1223.     ctok    MAX
  1224.     literal    0
  1225.     compqdo    spaces1
  1226. spaces0:
  1227.     ctok    SPACE
  1228.     comploop    spaces0
  1229. spaces1:
  1230.     ctok    UNNEST
  1231.  
  1232.     fnamemanque    <CHAR+>    ; c-addr1 -- c-addr2
  1233. fw_CHAR_PLUS:            ; CORE
  1234.     docode
  1235.     add    DWORD PTR [esp],tchar
  1236.     next
  1237.  
  1238.     fname    <CHARS>        ; n1 -- n2
  1239.     ctok    NEST        ; CORE
  1240.     literal    tchar
  1241.     ctok    STAR
  1242.     ctok    UNNEST
  1243.  
  1244.     fname    <FILL>        ; c-addr u char --
  1245.     docode            ; CORE
  1246.     pop    eax        ; char
  1247.     pop    ecx        ; count
  1248.     pop    edx        ; dest
  1249.     jecxz    fill_done    ; zero count? we're done before we start
  1250.     add    edx,dp        ; abs addr
  1251.     push    ds
  1252.     pop    es        ; same seg, this is default, but user might have changed it in a CODE word
  1253.     push    edi        ; save edi
  1254.     push    edx
  1255.     pop    edi        ; load destination
  1256.     rep    stosw        ; store char
  1257.     pop     edi        ; restore edi
  1258. fill_done:
  1259.     next
  1260.  
  1261. ;--( Strings )
  1262.  
  1263.     fnamemanque    </STRING>    ; c-addr1 u1 n -- c-addr2 u2
  1264. fw_SLSTRING:
  1265.     ctok    NEST
  1266.     ctok    ROT            ; -- u1 n c-a1
  1267.     ctok    OVER            ; -- u1 n c-a1 n
  1268.     ctok    CHARS            ; -- u1 n c-a1 nbytes
  1269.     ctok    PLUS            ; -- u1 n c-a2
  1270.     ctok    NEGROT            ; -- c-a2 u1 n
  1271.     ctok    MINUS            ; -- c-a2 u2
  1272.     ctok    UNNEST
  1273.  
  1274.     fname    <CMOVE>        ; c-addr1 c-addr2 u --
  1275.     ctok    NEST        ; STRING
  1276.     ctok    QDUP        ; -- c-addr1 c-addr2 [ u u | 0 ]
  1277.     ctok    ZEROEQ
  1278.     compif    cmove1
  1279.     ctok    TWO_DROP        ; --
  1280.     ctok    EXIT
  1281. cmove1:    literal    0
  1282.     compdo    cmove3
  1283. cmove2:    ctok    OVER        ; -- c-addr1 c-addr2 c-addr1
  1284.     ctok    C_FETCH        ; -- c-addr1 c-addr2 char
  1285.     ctok    OVER        ; -- c-addr1 c-addr2 char c-addr2
  1286.     ctok    C_STORE        ; -- c-addr1 c-addr2
  1287.     ctok    CHAR_PLUS    ; -- c-addr1 c-addr2'
  1288.     ctok    SWAP
  1289.     ctok    CHAR_PLUS    ; --  c-addr2' c-addr1'
  1290.     ctok    SWAP        ; -- c-addr1' c-addr2'
  1291.     comploop    cmove2
  1292. cmove3:    ctok    TWO_DROP
  1293.     ctok    UNNEST        ; --
  1294.  
  1295. ; Can't use our name header macros with this one!
  1296.     linkme    flinkptr
  1297.     countcell    6
  1298.     db    'C',0,'M',0,'O',0,'V',0,'E',0,'>',0        ; c-addr1 c-addr2 u --
  1299.     align    4            ; STRING
  1300. fw_CMOVER:
  1301.     ctok    NEST
  1302.     ctok    QDUP        ; -- c-addr1 c-addr2 [ u u | 0 ]
  1303.     ctok    ZEROEQ
  1304.     compif    cmover1
  1305.     ctok    TWO_DROP    ; --
  1306.     ctok    EXIT
  1307. cmover1:
  1308.     ctok    DUP        ; -- c-addr1 c-addr2  u u
  1309.     ctok    TO_R        ; -- c-addr1 c-addr2  u            R: -- u
  1310.     ctok    CHARS        ; -- c-addr1 c-addr2  u'         R: -- u
  1311.     ctok    TUCK        ; -- c-addr1 u' c-addr2 u'         R: -- u
  1312.     ctok    PLUS        ; -- c-addr1 u' c-addr2'         R: -- u
  1313.     ctok    TO_R        ; -- c-addr1 u'                 R: -- u c-addr2'
  1314.     ctok    PLUS        ; -- c-addr1'                 R: -- u c-addr2'
  1315.     ctok    R_FROM
  1316.     ctok    R_FROM        ; -- c-addr1' c-addr2' u
  1317.     literal    0
  1318.     compdo    cmover3
  1319. cmover2:
  1320.     literal    tchar        ; -- c-addr1' c-addr2' n
  1321.     ctok    MINUS        ; -- c-addr1' c-addr2''
  1322.     ctok    SWAP
  1323.     literal    tchar
  1324.     ctok    MINUS        ; -- c-addr2'' c-addr1''
  1325.     ctok    SWAP        ; -- c-addr1'' c-addr2''
  1326.     ctok    OVER        ; -- c-addr1'' c-addr2'' c-addr1''
  1327.     ctok    C_FETCH        ; -- c-addr1'' c-addr2'' char
  1328.     ctok    OVER        ; -- c-addr1'' c-addr2'' char c-addr2''
  1329.     ctok    C_STORE        ; -- c-addr1'' c-addr2''
  1330.     comploop    cmover2
  1331. cmover3:
  1332.     ctok    TWO_DROP        ; --
  1333.     ctok    UNNEST
  1334.  
  1335.     fname    <COUNT>        ; c-addr1 -- c-addr2 u
  1336.     docode
  1337.     mov    eax,[esp]
  1338.     xor    edx,edx
  1339.     mov    dx,[eax][dp]
  1340.     add    eax,tchar
  1341.     mov    [esp],eax
  1342.     push    edx
  1343.     next
  1344.  
  1345.     fname    <COMPARE>    ; c-addr1 u1 c-addr2 u2 -- n
  1346.     docode            ; STRING
  1347.     pop    ecx            ; u2
  1348.     pop    edx            ; c-addr2
  1349.     add    edx,dp            ; convert to abs addr
  1350.     pop    eax            ; u1
  1351.     cmp    ecx,eax            ; counts equal?
  1352.     je    compare_e        ; yes, continue further on
  1353.     jl    compare_u1        ; if u2 (in ecx) is lesser, continue further on
  1354.     mov    ecx,eax            ; u2 > u1
  1355.     mov    eax,[esp]        ; c-addr1
  1356.     add    eax,dp            ; convert to abs addr
  1357.     push    esi            ; preserve
  1358.     push    edi            ; preserve
  1359.     push    ds            ;
  1360.     pop    es            ; set ES, this is probably redundant in view of system requirements
  1361.     mov    esi,eax            ; c-addr1
  1362.     mov    edi,edx            ; c-addr2
  1363.     cld                ; direction upwards
  1364.     repe    cmpsw            ; unicode is 2-byte chars
  1365.     je    compare_neg1        ; all matched, u2 > u1
  1366.     mov    ax,[esi]
  1367.     cmp    ax,[edi]        ; compare non-match c-addr1 char to c-addr2 char
  1368.     jl    compare_neg1        ; c-addr1 char is less
  1369.     jmp    SHORT compare_1        ; c-addr2 char is less
  1370. compare_u1:                ; u1 > u2
  1371.     mov    eax,[esp]        ; c-addr1
  1372.     add    eax,dp            ; convert to abs addr
  1373.     push    esi            ; preserve
  1374.     push    edi            ; preserve
  1375.     push    ds            ;
  1376.     pop    es            ; set ES, this is probably redundant in view of system requirements
  1377.     mov    esi,eax            ; c-addr1
  1378.     mov    edi,edx            ; c-addr2
  1379.     cld                ; direction upwards
  1380.     repe    cmpsw            ; unicode is 2-byte chars
  1381.     je    compare_1        ; all matched, u1 > u2
  1382.     mov    ax,[esi]
  1383.     cmp    ax,[edi]        ; compare non-match c-addr1 char to c-addr2 char
  1384.     jl    compare_neg1        ; c-addr1 char is less
  1385.     jmp    SHORT compare_1        ; c-addr2 char is less
  1386. compare_e:                ; u1 = u2
  1387.     mov    eax,[esp]        ; c-addr1
  1388.     add    eax,dp            ; convert to abs addr
  1389.     push    esi            ; preserve
  1390.     push    edi            ; preserve
  1391.     push    ds            ;
  1392.     pop    es            ; set ES, this is probably redundant in view of system requirements
  1393.     mov    esi,eax            ; c-addr1
  1394.     mov    edi,edx            ; c-addr2
  1395.     cld                ; direction upwards
  1396.     repe    cmpsw            ; unicode is 2-byte chars
  1397.     je    compare_0        ; all matched
  1398.     mov    ax,[esi]
  1399.     cmp    ax,[edi]        ; compare non-match c-addr1 char to c-addr2 char
  1400.     jl    compare_neg1        ; c-addr1 char is less
  1401.     jmp    SHORT compare_1        ; c-addr2 char is less
  1402. compare_0:
  1403.     xor    eax,eax
  1404.     mov    2*cell[esp],eax        ; strings are equal and u1 = u2
  1405.     jmp    SHORT compare_done
  1406. compare_1:
  1407.     mov    eax,1
  1408.     mov    2*cell[esp],eax        ; char at first non-match in c-addr1 .gt. corresponding in c-addr2
  1409.     jmp    SHORT compare_done    ; or strings equal, and u1 > u2
  1410. compare_neg1:
  1411.     mov    eax,-1
  1412.     mov    2*cell[esp],eax        ; char at first non-match in c-addr1 .lt. corresponding in c-addr2
  1413.     jmp    SHORT compare_done    ; or strings equal, and u1 < u2
  1414. compare_done:
  1415.     pop    edi
  1416.     pop    esi
  1417.     next
  1418.  
  1419.     nname    <PLACE>        ; c-addr1 u c-addr2
  1420.     ctok    NEST        ; Not in Standard
  1421.     ctok    TWO_DUP        ; c-addr1 u c-addr2 u c-addr2
  1422.     ctok    C_STORE        ; c-addr1 u c-addr2
  1423.     ctok    CHAR_PLUS    ; c-addr1 u c-addr2'
  1424.     ctok    SWAP        ; c-addr1 c-addr2' u
  1425.     ctok    CHARS        ; c-addr1 c-addr2' u'
  1426.     ctok    MOVE        ; --
  1427.     ctok    UNNEST
  1428.  
  1429.     nname    <SKIP>        ; ( c-addr1 u1 char --- c-addr2 u2)
  1430.     docode            ; Not in standard, skip to first non-match
  1431.     pop    eax        ; -- c-addr u1
  1432.     pop    ecx        ; -- c-addr1        u count to iteration register
  1433.     pop    edx        ; --            address of start of string
  1434.     add    edx,dp        ; --            add offset to base of data region, forming absolute address
  1435.     push    edi        ; -- edi            preserve edi
  1436.     push    ds        ; -- edi ds
  1437.     pop    es        ; -- edi            load es from ds
  1438.     push    edx        ; -- edi abs-addr1
  1439.     pop    edi        ; -- edi            load edi
  1440.     cld            ; ascending search
  1441.     repe    scasw        ; search for non-match
  1442.     je    skip_fail    ; zero is set if no non-match was found
  1443.     pop    eax        ; --            saved di
  1444.     push    edi        ; -- abs-addr2        address after end of string, abs
  1445.     pop    edx        ; --            get it back
  1446.     sub    edx,tchar    ; --            move it back to point to non-match char
  1447.     sub    edx,dp        ; --            convert back to data-relative address
  1448.     push    edx        ; -- c-addr2        return it
  1449.     inc    ecx        ; -- c-addr2        back count up to match point
  1450.     push    ecx        ; -- c-addr2 u2        return count of remainder of string
  1451.     push    eax        ; -- c-addr2 u2 di
  1452.     pop    edi        ; -- c-addr2 u2        restore edi
  1453.     next
  1454. skip_fail:
  1455.     pop    eax        ; saved edi
  1456.     push    edi        ; address after end of string, abs
  1457.     pop    edx        ; get it back
  1458.     sub    edx,dp        ; convert back to data-relative address
  1459.     push    edx        ; return it
  1460.     push    ecx        ; return zero which will be in ecx in this branch
  1461.     push    eax        ; that ol' saved di
  1462.     pop    edi        ; restore, -- c-addr2 u2
  1463.     next
  1464.  
  1465.     nname    <SCAN>        ; ( c-addr1 u1 char --- c-addr2 u2)
  1466.     docode            ; Not in Standard, point to head of substring c-addr2 u2 where char first found
  1467.     pop    eax        ; char
  1468.     pop    ecx        ; count to iteration register
  1469.     pop    edx        ; address of start of string
  1470.     add    edx,dp        ; add offset to base of data seg
  1471.     push    edi        ; save edi
  1472.     push    ds
  1473.     pop    es        ; load es from ds
  1474.     push    edx
  1475.     pop    edi        ; load edi
  1476.     cld            ; ascending search
  1477.     repne    scasw        ; search for match
  1478.     jne    scan_fail    ; zero is set if char was ever found
  1479.     pop    eax        ; saved edi
  1480.     push    edi        ; address after end of string, abs
  1481.     pop    edx        ; get it back
  1482.     sub    edx,tchar    ; move it back to match char
  1483.     sub    edx,dp        ; convert back to data-relative address
  1484.     push    edx        ; return it
  1485.     inc    ecx        ; back count up to match point
  1486.     push    ecx        ; return count of remainder of string
  1487.     push    eax        ; that ol' saved edi
  1488.     pop    edi        ; restore, -- c-addr2 u2
  1489.     next
  1490. scan_fail:
  1491.     pop    eax        ; saved edi
  1492.     push    edi        ; address after end of string, abs
  1493.     pop    edx        ; get it back
  1494.     sub    edx,dp        ; convert back to data-relative address
  1495.     push    edx        ; return it
  1496.     push    ecx        ; return zero which will be in ecx in this branch
  1497.     push    eax        ; that ol' saved edi
  1498.     pop    edi        ; restore, -- c-addr2 u2
  1499.     next
  1500.  
  1501.     fnamemanque    <-TRAILING>    ; c-addr1 u1 -- c-addr1 u2
  1502. fw_DASH_TRAILING:            ; STRING
  1503.     docode
  1504.     mov    ecx,[esp]    ; count
  1505.     mov    edx,cell[esp]    ; string address
  1506.     add    edx,ecx        ; do this twice to handle wide character size
  1507.     add    edx,ecx        ; point past end of string
  1508.     sub    edx,tchar    ; point to last character in string
  1509.     add    edx,dp        ; absolute address
  1510.     mov    ax,20h        ; blank
  1511.     push    edi        ; preserve edi
  1512.     push    edx        ; end-of-string abs address
  1513.     pop    edi        ; load edi
  1514.     push    ds
  1515.     pop    es        ; same seg, probably redundant
  1516.     std            ; backwards search
  1517.     repe    scasw        ; seek non-match with char
  1518.     je    none_trailing    ; no non-blanks
  1519.     pop    edi        ; restore edi
  1520.     inc    cx        ; adjust count to point back to end of string
  1521.     mov    [esp],ecx    ; new count
  1522.     cld            ; !!!***!!! important, NEXT won't work unless direction flag set this way
  1523.     next
  1524. none_trailing:                ; no non-blanks at all
  1525.     pop    edi            ; restore edi
  1526.     mov    DWORD PTR [esp],FALSE    ; zero count
  1527.     cld            ; !!!***!!! important, NEXT won't work unless direction flag set this way
  1528.     next
  1529.  
  1530.     finame    <SLITERAL>    ; c-addr1 u    Execution: -- c-addr2 u
  1531.     ctok    NEST        ; STRING
  1532.     ctok    STATEABORT
  1533.     ctok    ALIGN
  1534.     ctok    DUP        ; -- c-addr1 u u
  1535.     ctok    HERE        ; -- c-addr1 u u here
  1536.     ctok    TWO_SWAP    ; -- u here c-addr1 u
  1537.     ctok    HERE        ; -- u here c-addr1 u here
  1538.     ctok    PLACE        ; -- u here
  1539.     ctok    DOLIT
  1540.     ctok    DOSQUOTE    ; -- u here xt
  1541.     ctok    COMPCOMMA
  1542.     ctok    COMPCOMMA    ; -- u
  1543.     ctok    ONE_PLUS    ; -- u'        account for count character
  1544.     ctok    CHARS        ; -- chars
  1545.     ctok    ALLOT        ; --
  1546.     ctok    UNNEST
  1547.  
  1548. ; Can't use our name header macros with this one!
  1549.     linkme    flinkptr
  1550.     countcell    <2 or immedMask>
  1551.     db    'S',0,'"',0        ; Interp: "ccc<"> -- c-addr u    Compile: "ccc<"> -- Execute: c-addr u
  1552.     align    4            ; FILE
  1553. fw_S_QUOTE:
  1554.     ctok    NEST
  1555.     charlit    '"'            ; -- char
  1556.     ctok    PARSE            ; -- c-addr u
  1557.     ctok    STATE            ; -- c-addr u a-addr
  1558.     ctok    FETCH            ; -- c-addr u flag
  1559.     compif    s_quote1        ; are we compiling?
  1560.     ctok    ALIGN            ; for good luck -- maybe this should be removed
  1561.     ctok    HERE            ; -- c-addr1 u c-addr2
  1562.     ctok    DUP            ; -- c-addr1 u c-addr2 c-addr2
  1563.     ctok    TO_R            ; -- c-addr1 u c-addr2        R: -- c-addr2
  1564.     ctok    OVER            ; -- c-addr1 u c-addr2 u    R: -- c-addr2
  1565.     ctok    ONE_PLUS        ; -- c-addr1 u c-addr2 u'    R: -- c-addr2
  1566.     ctok    CHARS            ; -- c-addr1 u c-addr2 chars    R: -- c-addr2
  1567.     ctok    ALLOT            ; -- c-addr1 u c-addr2        R: -- c-addr2
  1568.     ctok    PLACE            ; --                 R: -- c-addr2
  1569.     literal    0
  1570.     ctok    CCOMMA            ; --    null pad
  1571.     ctok    DOLIT
  1572.     ctok    DOSQUOTE        ; -- xt                R: -- c-addr2
  1573.     ctok    COMPCOMMA        ; --                 R: -- c-addr2
  1574.     ctok    R_FROM            ; -- c-addr2            R: --
  1575.     ctok    COMPCOMMA        ; --
  1576.     ctok    EXIT
  1577. s_quote1:
  1578.     literal    stringBuffer        ; -- c-addr1 u c-addr2
  1579.     ctok    PLACE            ; --
  1580.     literal    stringBuffer        ; -- c-addr2
  1581.     ctok    COUNT            ; -- c-addr2 u
  1582.     ctok    TWO_DUP
  1583.     ctok    CHARS
  1584.     ctok    PLUS
  1585.     literal    0
  1586.     ctok    SWAP
  1587.     ctok    C_STORE            ; append null terminator
  1588.     ctok    UNNEST
  1589.  
  1590. ; Can't use our name header macros with this one!
  1591.     linkme    flinkptr
  1592.     countcell    <2 or immedMask>
  1593.     db    '.',0,'"',0        ; Interp: -- c-addr u    Compile --
  1594.     align    4            ; CORE
  1595. fw_DOT_QUOTE:
  1596.     ctok    NEST
  1597.     ctok    STATEABORT
  1598.     ctok    DP
  1599.     ctok    FETCH            ; -- dictionary-pointer
  1600.     ctok    S_QUOTE            ; -- dp        S" has stored string and embedded execution engine
  1601.     ctok    DOLIT
  1602.     ctok    DODOTQUOTE
  1603.     ctok    SWAP            ; -- xt dp
  1604.     ctok    CODETODATA
  1605.     ctok    STORE            ; --        overwrite S" exe engine with ." exe engine
  1606.     ctok    UNNEST
  1607.  
  1608.     fname    <PAD>            ; -- c-addr
  1609.     ctok    DOCONST            ; CORE EXT
  1610.     dd    tickpad
  1611.  
  1612. ;--( Number Conversion )
  1613.  
  1614.     fname    <BASE>        ; a-addr
  1615.     ctok    DOCONST        ; CORE
  1616.     dd    var_base
  1617.  
  1618.     fname    <DECIMAL>    ; --
  1619.     ctok    NEST        ; CORE
  1620.     literal    10
  1621.     ctok    BASE
  1622.     ctok    STORE
  1623.     ctok    UNNEST
  1624.  
  1625.     fname    <HEX>        ; --
  1626.     ctok    NEST        ; CORE
  1627.     literal    16
  1628.     ctok    BASE
  1629.     ctok    STORE
  1630.     ctok    UNNEST
  1631.  
  1632.     fname    <HLD>        ; a-addr
  1633.     ctok    DOCONST        ; Implementation detail
  1634.     dd    var_hld
  1635.  
  1636.     fname    <HOLD>        ; char --
  1637.     ctok    NEST        ; CORE
  1638.     literal    -1
  1639.     ctok    CHARS
  1640.     ctok    HLD
  1641.     ctok    PL_STORE    ; predecrement offset pointer which was set by <#
  1642.     ctok    HLD
  1643.     ctok    FETCH
  1644.     ctok    C_STORE        ; store character in numeric format buffer
  1645.     ctok    UNNEST
  1646.  
  1647. ; Is char a digit in base n?
  1648.     nname    <DIGIT>        ; char n1 -- n2 true | char false
  1649.     docode            ; Not in Standard
  1650.     pop    edx        ; base
  1651.     pop    eax        ; char
  1652.     mov    ecx,eax        ; save copy of char
  1653.     sub    ax,'0'        ; is char >= '0'
  1654.     jb    not_digit    ; if not, jump not_digit
  1655.     cmp    ax,9        ; is char <= 9
  1656.     jbe    digit1        ; yes, jump to digit_1
  1657.     cmp    ax,'A'-'0'    ; no, see if it's an alpha number
  1658.     jb    not_digit    ; it ain't, jump away
  1659.     sub    ax,'A'-'0'-10    ; it is, subtract offset of that portion of char set to make correct digit
  1660. digit1:    cmp    ax,dx        ; now compare resultant number to base
  1661.     jnb    not_digit    ; it ain't a digit if it ain't below the value of the base
  1662.     push    eax        ; it is a digit, push
  1663.     push    TRUE        ; TRUE for success
  1664.     next
  1665. not_digit:
  1666.     push    ecx        ; char
  1667.     xor    eax,eax        ; false, failure
  1668.     push    eax
  1669.     next
  1670.  
  1671.     nname    <DPL>        ; -- a-addr
  1672.     ctok    DOCONST        ; Not in Standard
  1673.     dd    var_dpl
  1674.  
  1675.     nname    <NUMBER>    ; c-addr1 u1 -- d TRUE | x x FALSE
  1676.     ctok    NEST        ; Not in Standard
  1677.     ctok    TRUE
  1678.     ctok    DPL
  1679.     ctok    STORE        ; indicate no dot in number input as default
  1680.     ctok    OVER        ; -- c-a1 u1 c-a1
  1681.     ctok    C_FETCH        ; -- c-a1 u1 char
  1682.     charlit    '-'        ; -- c-a1 u1 char1 char2
  1683.     ctok    EQUAL        ; -- c-a1 u1 flag
  1684.     ctok    DUP        ; -- c-a1 u1 flag flag
  1685.     ctok    TO_R        ; -- c-a1 u1 flag flag            R: -- flag    save negative flag
  1686.     compif    number1        ; was there a prepended negative sign?
  1687.     ctok    ONE_MINUS    ; -- c-a1 u1'                R: -- flag    yes, dec count
  1688.     ctok    SWAP
  1689.     ctok    CHAR_PLUS    ; -- u1' c-a1'                R: -- flag    advance address
  1690.     ctok    SWAP        ; -- c-a1' u1'                R: -- flag
  1691. number1:
  1692.     ctok    FALSE
  1693.     ctok    FALSE        ; -- c-a1' u1' ud            R: -- flag
  1694.     ctok    TWO_SWAP    ; -- ud c-a1' u1'            R: -- flag
  1695. number2:
  1696.     ctok    TO_NUMBER    ; -- ud c-a2 u2                R: -- flag
  1697.     ctok    QDUP        ; -- ud c-a2 [ u2 u2 | 0 ]        R: -- flag
  1698.     compif    number_success    ; did number conversion complete leave non-zero count of chars left?
  1699.     ctok    OVER        ; -- ud c-a2 u2 c-a2            R: -- flag
  1700.     ctok    C_FETCH        ; -- ud c-a2 u2 char            R: -- flag
  1701.     charlit    '.'        ; -- ud c-a2 u2 char1 char2        R: -- flag
  1702.     ctok    EQUAL        ; -- ud c-a2 u2 flag            R: -- flag
  1703.     compif    number_fail    ; was the character which stopped the conversion a "dot"?
  1704.     ctok    DUP        ; -- ud c-a2 u2 u2        R: -- flag
  1705.     ctok    ONE_MINUS    ; -- ud c-a2 u2 u2'        R: -- flag
  1706.     ctok    DPL        ; -- ud c-a2 u2 u2' a-addr    R: -- flag    ; right-justified count to dot-place-marker
  1707.     ctok    STORE        ; -- ud c-a2 u2            R: -- flag
  1708.     ctok    ONE_MINUS    ; -- ud c-a2 u2'        R: -- flag
  1709.     ctok    SWAP        ; -- ud u2' c-a2        R: -- flag
  1710.     ctok    CHAR_PLUS    ; -- ud u2' c-a2'        R: -- flag
  1711.     ctok    SWAP        ; -- ud c-a2' u2'        R: -- flag
  1712.     ctok    DUP        ; -- ud c-a2' u2'        R: -- flag
  1713.     ctok    DOUNTILNOT    ; more chars? try it some more! This allows multiple dots in a number ... sounds ok
  1714.     dd    number2        ; otherwise, we're done if parsing the "dot" exhausted the string
  1715.     ctok    DROP        ; -- ud c-a2'            R: -- flag
  1716.     compelse    number_success
  1717. number_fail:            ; -- ud c-a u            R: -- flag
  1718.     ctok    TWO_DROP    ; -- ud                R: -- flag
  1719.     ctok    FALSE        ; -- ud 0            R: -- flag
  1720.     ctok    R_FROM        ; -- ud 0 flag            R: -- 
  1721.     ctok    DROP        ; -- ud 0
  1722.     ctok    EXIT        ; -- x x 0
  1723. number_success:            ; -- ud c-addr            R: -- flag
  1724.     ctok    DROP        ; -- ud                R: -- flag
  1725.     ctok    R_FROM        ; -- ud flag            R: --
  1726.     compif    number_done    ; did we mark this negative?
  1727.     ctok    DNEGATE        ; -- d
  1728. number_done:
  1729.     ctok    TRUE        ; -- d true
  1730.     ctok    UNNEST
  1731.  
  1732. ; Can't use our name header macros with this one!
  1733.     linkme    flinkptr
  1734.     countcell    7
  1735.     db    '>',0,'N',0,'U',0,'M',0,'B',0,'E',0,'R',0    ; ud1 c-addr1 u1 -- ud2 c-addr2 u2
  1736. fw_TO_NUMBER:
  1737.     ctok    NEST
  1738. tonum1:    ctok    DUP        ; BEGIN -- ud1 c-addr1 u1 u1
  1739.     compif    tonum4        ; WHILE
  1740.     ctok    SWAP        ; -- ud1 u1 c-addr1
  1741.     ctok    COUNT        ; -- ud1 u1 c-addr char
  1742.     ctok    BASE        ; -- ud1 u1 c-addr char a-addr
  1743.     ctok    FETCH        ; -- ud1 u1 c-addr char n
  1744.     ctok    DIGIT        ; -- ud1 u1 c-addr n flag
  1745.     compif    tonum2        ; if it's a digit
  1746.     ctok    TO_R        ; -- ud1 u1 c-addr            R: -- n
  1747.     ctok    TWO_SWAP    ; -- u1 c-addr ud1            R: -- n
  1748.     ctok    BASE
  1749.     ctok    FETCH        ; -- u1 c-addr ud1 n            R: -- n
  1750.     ctok    UDSTARU        ; -- u1 c-addr ud            R: -- n
  1751.     ctok    R_FROM
  1752.     literal    0        ; -- u1 c-addr ud "udx"            R: --
  1753.     ctok    D_PLUS        ; -- u1 c-addr ud'
  1754.     ctok    TWO_SWAP    ; -- ud' u1 c-addr
  1755.     ctok    SWAP        ; -- ud2 c-addr u1
  1756.     compelse    tonum3    ; ELSE
  1757. tonum2:    ctok    DROP        ; -- ud2 u2 c-addr
  1758.     literal    tchar
  1759.     ctok    MINUS        ; -- ud2 u2 c-addr2
  1760.     ctok    SWAP        ; -- ud2 c-addr2 u2
  1761.     ctok    EXIT        ; THEN
  1762. tonum3:    ctok    ONE_MINUS    ; -- ud c-addr u
  1763.     compelse    tonum1    ; REPEAT
  1764. tonum4:    ctok    UNNEST        ; -- ud2 c-addr2 u2
  1765.  
  1766. ; Can't use our name header macros with this one!
  1767.     linkme    flinkptr
  1768.     countcell    2
  1769.     db    '<',0,'#',0    ; --
  1770.     align    4            ; CORE
  1771. fw_LSHARP:
  1772.     ctok    NEST
  1773.     literal    ticknumend
  1774.     ctok    HLD
  1775.     ctok    STORE        ; set up pointer to numeric output string format buffer
  1776.     ctok    UNNEST
  1777.  
  1778.     fnamemanque    <#>    ; ud1 -- ud2
  1779. fw_SHARP:
  1780.     ctok    NEST
  1781.     ctok    BASE
  1782.     ctok    FETCH
  1783.     ctok    DUMSLMOD    ; -- r ud'
  1784.     ctok    ROT
  1785.     ctok    DUP
  1786.     literal    10
  1787.     ctok    LESS        ; -- ud' r flag        ; is this within the numeric Unicode chars?
  1788.     compif    sharp1
  1789.     ctok    DOLIT
  1790.     db    '0',0,0,0    ; -- ud' r char        ; yes, we'll need to add its number to the char '0'
  1791.     compelse sharp2
  1792. sharp1:    literal    'A'-10        ; -- ud' r char        ; no we'll need to add its number to an offset from 'A'
  1793. sharp2:    ctok    PLUS        ; -- ud' char'
  1794.     ctok    HOLD        ; -- ud'        ; store char
  1795.     ctok    UNNEST
  1796.  
  1797.     fnamemanque    <#S>    ; ud1 -- ud2
  1798. fw_SHARPS:
  1799.     ctok    NEST
  1800. sharps:
  1801.     ctok    SHARP        ; -- ud'        loop converting chars
  1802.     ctok    TWO_DUP        ; -- ud' ud'
  1803.     ctok    OR        ; -- ud' flag
  1804.     ctok    DOUNTILNOT    ; -- ud'        loop until it's 0.0
  1805.     dd    sharps
  1806.     ctok    UNNEST
  1807.     
  1808. ; Can't use our name header macros with this one!
  1809.     linkme    flinkptr
  1810.     countcell    2
  1811.     db    '#',0,'>',0    ; ud -- c-addr u
  1812.     align    4        ; CORE
  1813. fw_SHARPR:
  1814.     ctok    NEST
  1815.     ctok    TWO_DROP    ; --            discard what's left of double which was to be formatted
  1816.     ctok    HLD        
  1817.     ctok    FETCH        ; -- c-addr
  1818.     literal    ticknumend    ; -- c-addr1 c-addr2
  1819.     ctok    OVER        ; -- c-addr1 c-addr2
  1820.     ctok    MINUS        ; -- c-addr1 n
  1821.     literal    1
  1822.     ctok    CHARS        ; -- c-addr1 n sizeofchar    address diff has to be divided by char size
  1823.     ctok    SLASH        ; -- c-addr u
  1824.     ctok    UNNEST
  1825.  
  1826. ;--( I/O )
  1827.  
  1828.     fname    <CR>    ; --
  1829.     ctok    NEST    ; CORE
  1830.     literal    0DH
  1831.     ctok    EMIT
  1832.     literal    0AH
  1833.     ctok    EMIT
  1834.     ctok    UNNEST
  1835.  
  1836.     fname    <SIGN>    ; n --
  1837.     ctok    NEST    ; CORE
  1838.     ctok    ZEROLT
  1839.     compif    sign1
  1840.     charlit    '-'
  1841.     ctok    HOLD    
  1842. sign1:    ctok    UNNEST
  1843.  
  1844.     fnamemanque    <.>    ; n --
  1845. fw_DOT:    ctok    NEST        ; CORE
  1846.     ctok    PDOT
  1847.     ctok    TYPE        ; --
  1848.     ctok    BL
  1849.     ctok    EMIT
  1850.     ctok    UNNEST
  1851.  
  1852.     fnamemanque    <.R>    ; n1 n2 --
  1853. fw_DOT_R:
  1854.     ctok    NEST        ; CORE EXT
  1855.     ctok    SWAP        ; -- n2 n1            
  1856.     ctok    PDOT        ; -- n2 c-addr u
  1857.     ctok    ROT        ; -- c-addr u n2
  1858.     ctok    OVER        ; -- c-addr u n2 u
  1859.     ctok    MINUS        ; -- c-addr u1 u2
  1860.     literal    0
  1861.     ctok    MAX        ; -- c-addr u1 u2'
  1862.     ctok    SPACES        ; -- c-addr u
  1863.     ctok    TYPE        ; --
  1864.     ctok    UNNEST
  1865.  
  1866.     znamemanque    <(.)>    ; n -- c-addr u
  1867. fw_PDOT:
  1868.     ctok    NEST
  1869.     ctok    DUP        ; -- n n
  1870.     ctok    ABS        ; -- n _n_
  1871.     ctok    S_TO_D        ; -- n d
  1872.     ctok    LSHARP        ; -- n d
  1873.     ctok    SHARPS        ; -- n d'
  1874.     ctok    ROT        ; -- d' n
  1875.     ctok    SIGN        ; -- d
  1876.     ctok    SHARPR        ; -- c-addr u
  1877.     ctok    UNNEST
  1878.  
  1879.     fnamemanque    <D.>    ; d --
  1880. fw_D_DOT:
  1881.     ctok    NEST        ; CORE
  1882.     ctok    TUCK        ; -- dh d
  1883.     ctok    DABS        ; -- dh _d_
  1884.     ctok    LSHARP        ; -- dh _d_
  1885.     ctok    SHARPS        ; -- dh d'
  1886.     ctok    ROT        ; -- d' dh
  1887.     ctok    SIGN        ; -- d'
  1888.     ctok    SHARPR        ; -- c-addr u
  1889.     ctok    TYPE        ; --
  1890.     ctok    BL
  1891.     ctok    EMIT
  1892.     ctok    UNNEST
  1893.  
  1894.     fnamemanque    <U.>    ; u --
  1895. fw_U_DOT:            ; CORE
  1896.     ctok    NEST
  1897.     literal    0
  1898.     ctok    UD_DOT
  1899.     ctok    UNNEST
  1900.  
  1901.     nnamemanque    <UD.>    ; ud --
  1902. fw_UD_DOT:            ; Not in Standard
  1903.     ctok    NEST
  1904.     ctok    LSHARP
  1905.     ctok    SHARPS
  1906.     ctok    SHARPR
  1907.     ctok    TYPE
  1908.     ctok    BL
  1909.     ctok    EMIT
  1910.     ctok    UNNEST
  1911.  
  1912.     fnamemanque    <.S>    ; i*x -- i*x
  1913. fw_DOT_S:            ; CORE EXT
  1914.     ctok    NEST
  1915.     ctok    DEPTH
  1916.     literal    0
  1917.     ctok    MAX
  1918.     ctok    DUP
  1919.     literal    0
  1920.     compqdo    dot_s1
  1921. dot_s0:
  1922.     ctok    DUP
  1923.     ctok    I
  1924.     ctok    MINUS
  1925.     ctok    PICK
  1926.     ctok    U_DOT
  1927.     comploop    dot_s0
  1928. dot_s1:    ctok    DROP
  1929.     ctok     UNNEST
  1930.  
  1931.     zname    <DEBDOTS>    ; i*j char -- i*j
  1932.     ctok    NEST
  1933.     ctok    EMIT
  1934.     ctok    SPACE
  1935.     ctok    DOT_S
  1936.     ctok    KEY
  1937.     ctok    DROP
  1938.     ctok    CR
  1939.     ctok    UNNEST
  1940.     
  1941.     fname    <KEY>    ; -- char
  1942.     docode        ; CORE
  1943.     xor    ecx,ecx                    ; clear character holder
  1944.     lea    eax,[dp+conMode]            ; in order to preserve con mode
  1945.     stdCall    _GetConsoleMode,<[dp+stdIn],eax>    ; let's find out what it is
  1946.     and    eax,eax                    ; success is "C" TRUE
  1947.     jne    key2                    ; if GetConsoleMode succeeds, continue
  1948.     mov    eax,UniNotAChar                ; on failure, push invalid char
  1949.     push    eax
  1950.     jmp    doLastErr                ; return to NEXT via doLastErr
  1951. key2:    stdCall    _SetConsoleMode,<[dp+stdIn],0>        ; set no echo, no line input, no window/mouse/processed
  1952.     and    eax,eax                    ; success is "C" TRUE
  1953.     jne    key3                    ; if SetConsoleMode succeeds, continue
  1954.     mov    eax,UniNotAChar                ; on failure, push invalid char
  1955.     push    eax
  1956.     jmp    doLastErr                ; return to NEXT via doLastErr
  1957. key3:    stdCall    _ReadConsoleW,<[dp+stdIn],OFFSET FLAT:lastReadConW,1,OFFSET FLAT:numRead,0>    ; get a char
  1958.     and    eax,eax                ; "C" TRUE is success
  1959.     je    key4                ; on failure, get error code
  1960.     mov    DWORD PTR lastError[dp],TRUE    ; success, return TRUE, no Windows error code has all bits set
  1961.     cmp    DWORD PTR numRead,0        ; did we get any?
  1962.     je    key3                ; loop waiting
  1963.     xor    ecx,ecx                ; clear for character
  1964.     mov    cx,WORD PTR lastReadConW    ; retrieve char, ecx ostensibly clear for now
  1965.     push    ecx                ; push to stack
  1966.     mov    eax,conMode[dp]            ; get saved console mode
  1967.     stdCall    _SetConsoleMode,<[dp+stdIn],eax>    ; restore previous console mode, don't worry about err here
  1968.     next    
  1969. key4:    stdCall    _GetLastError            ; on this error, don't worry about console mode
  1970.     mov    lastError[dp],eax        ; save error return
  1971.     mov    eax,UniNotAChar
  1972.     push    eax
  1973.     next
  1974.  
  1975. ;!!!***!!! This still doesn't work right
  1976.     fnamemanque    <KEY?>                ; -- flag
  1977. fw_KEY_Q:                        ; FACILITY
  1978.     docode
  1979.     mov    DWORD PTR lastError[dp],TRUE        ; No windows error code has all bits set
  1980.     mov    eax,256                    ; number of records to try for per Microsoft
  1981.     stdCall    _PeekConsoleInputW <[dp+stdIn], OFFSET FLAT:inRecArray, eax, OFFSET FLAT:numRead>
  1982.     and    eax,eax                    ; "C" TRUE is success
  1983.     jne    keyq1                    ; on success, continue further on
  1984.     push    eax                    ; push failure
  1985.     jmp    doLastErr                ; on failure, return via set error code routine
  1986. keyq1:     mov    ecx,[numRead]                ; number of input records successfully peeked
  1987.     and    ecx,ecx
  1988.     je    keyq_none                ; none? fergit it!
  1989.     mov    eax,OFFSET FLAT:inRecArray
  1990. keyq2:    cmp    WORD PTR [eax].EventType,KEY_EVENT    ; loop comparing the EvenType field in each struc
  1991.     jne    keyq_continue                ; not a KEY_EVENT, loop
  1992.     cmp    DWORD PTR [eax].bKeyDown,0        ; test if we have a key down
  1993.     jne    keyq_found                ; if C-language "true", a key is down, we're done
  1994. keyq_continue:
  1995.     add    eax,SIZE INPUT_RECORD
  1996.     loop    keyq2
  1997. keyq_none:                        ; nope
  1998.     push    FALSE
  1999.     next
  2000. keyq_found:                        ; yup
  2001.     push    TRUE
  2002.     next
  2003.  
  2004.     fname    <TYPE>        ; c-addr u --
  2005.     dd    ftype
  2006. ftype:    pop    eax
  2007.     pop    edx
  2008.     lea    edx,[edx][dp]
  2009.     stdCall    _WriteConsoleW,<[dp+stdOut],edx,eax,OFFSET FLAT:numWritten,0>
  2010.     jmp    SHORT    doLastErr        ; returns to NEXT via doLastErr
  2011.  
  2012.     fname    <EMIT>
  2013.     dd    emit
  2014. emit:    pop    DWORD PTR [dp+outChar]
  2015.     lea    eax,[dp+outChar]
  2016.     stdCall    _WriteConsoleW,<[dp+stdOut],eax,1,OFFSET FLAT:numWritten,0>
  2017.     jmp    SHORT    doLastErr        ; returns to NEXT via doLastErr
  2018.  
  2019. ; Serve these I/O words to set our local LastError variable either TRUE for success or to return from LastError.
  2020. doLastErr:
  2021.     and    eax,eax                ; "C" TRUE is success
  2022.     je    dLE1                ; on failure, get error code
  2023.     mov    DWORD PTR lastError[dp],TRUE    ; success, return TRUE
  2024.     next                    ; No Windows error code has all bits set
  2025. dLE1:    stdCall    _GetLastError
  2026.     mov    lastError[dp],eax        ; save error return
  2027.     next
  2028.  
  2029. ; Calls factor (ACCEPT), then handles trailing CR/LF pair.
  2030.     fname    <ACCEPT>    ; c-addr +n1 -- +n2
  2031.     ctok    NEST
  2032.     ctok    OVER
  2033.     ctok    SWAP        ; -- c-a c-a +n1
  2034.     ctok    PACCEPT        ; -- c-a +n2'
  2035.     ctok    DUP        ; -- c-a +n2 +n2
  2036.     compif    accept9
  2037.     ctok    TWO_DUP        ; -- c-a +n2 c-a +n2
  2038.     ctok    CHARS
  2039.     ctok    PLUS        ; -- c-a1 +n2 c-a2
  2040.     literal    2
  2041.     literal    0
  2042.     compdo    accept4
  2043. accept3:
  2044.     literal    1        ; -- c-a1 +n2 c-a2 1
  2045.     ctok    CHARS
  2046.     ctok    MINUS        ; -- c-a1 +n2 c-a2'
  2047.     ctok    DUP
  2048.     ctok    C_FETCH        ; -- c-a1 +n2 c-a2' char
  2049.     ctok    DUP
  2050.     literal    0aH        ; -- c-a1 +n2 c-a2' char char 0aH
  2051.     ctok    EQUAL        ; -- c-a1 +n2 c-a2' char flag
  2052.     ctok    SWAP        ; -- c-a1 +n2 c-a2' flag char
  2053.     literal    0dH        ; -- c-a1 +n2 c-a2' flag char 0dH
  2054.     ctok    EQUAL        ; -- c-a1 +n2 c-a2' flag1 flag2
  2055.     ctok    OR        ; -- c-a1 +n2 c-a2' flag
  2056.     compif    accept8
  2057.     ctok    BL        ; -- c-a1 +n2 c-a2' 020H
  2058.     ctok    OVER        ; -- c-a1 +n2 c-a2' 020H c-a2'
  2059.     ctok    C_STORE        ; -- c-a1 +n2 c-a2'
  2060. accept8:
  2061.     comploop    accept3
  2062. accept4:            ; -- c-a1 +n2 c-a2'
  2063.     ctok    DROP        ; -- c-a1 +n2
  2064. accept9:
  2065.     ctok    NIP        ; -- +n2
  2066. accept_done:
  2067.     ctok    UNNEST
  2068.  
  2069.     znamemanque    <(ACCEPT)>    ; c-addr +n1 -- +n2
  2070. fw_PACCEPT:                ; implementation
  2071.     docode
  2072.     pop    eax
  2073.     and    eax,eax                    ; positive count?
  2074.     jnle    paccept1                ; if yes, continue further on
  2075.     xor    eax,eax                    ; make a zero
  2076.     mov    [esp],eax                ; +n2 = 0 on error
  2077. paccept1:
  2078.     push    eax                    ; preserve count
  2079.     lea    eax,[dp+conMode]            ; in order to preserve con mode
  2080.     stdCall    _GetConsoleMode,<[dp+stdIn],eax>    ; let's find out what it is
  2081.     and    eax,eax                    ; success is "C" TRUE
  2082.     jne    paccept2                ; if GetConsoleMode succeeds, continue
  2083.     pop    eax                    ; discard count
  2084.     xor    eax,eax                    ; make a zero
  2085.     mov    [esp],eax                ; n2 = 0 on error
  2086.     jmp    doLastErr                ; return to NEXT via doLastErr
  2087. paccept2:
  2088.     stdCall    _SetConsoleMode,<[dp+stdIn],ENABLE_ECHO_INPUT OR ENABLE_LINE_INPUT OR ENABLE_PROCESSED_INPUT>
  2089.             ; set echo, line input, processed handling
  2090.     and    eax,eax                    ; success is "C" TRUE
  2091.     jne    paccept3                ; if SetConsoleMode succeeds, continue
  2092.     pop    eax                    ; discard count
  2093.     xor    eax,eax                    ; make a zero
  2094.     mov    [esp],eax                ; n2 = 0 on error
  2095.     jmp    doLastErr                ; return to NEXT via doLastErr
  2096. paccept3:
  2097.     pop    eax                    ; count
  2098.     pop    edx                    ; destination
  2099.     add    edx,dp                    ; abs address of destination
  2100.     stdCall    _ReadConsoleW,<[dp+stdIn],edx,eax,OFFSET FLAT:numRead,0>    ; get a line of input
  2101.     and    eax,eax                    ; "C" TRUE is success
  2102.     jne    paccept4                ; on success, continue elsewhere
  2103.     push    eax
  2104.     jmp    doLastErr                ; failure, get error code
  2105. paccept4:
  2106.     mov    DWORD PTR lastError[dp],TRUE    ; success, return TRUE, no Windows error code has all bits set
  2107.     mov    eax,DWORD PTR numRead        ; how many did we get?
  2108.     push    eax                ; this is: -- +n2
  2109.     mov    eax,conMode[dp]            ; get saved console mode
  2110.     stdCall    _SetConsoleMode,<[dp+stdIn],eax>    ; restore previous console mode, don't worry about err here
  2111.     next
  2112.  
  2113. ;--( Data Space and the Dictionary )
  2114.  
  2115.     zname    <UNFOUND>    ; --
  2116.     ctok    NEST        ; Implementation 
  2117.     literal    wordBuffer
  2118.     ctok    COUNT
  2119.     ctok    TYPE
  2120.     ctok    SPACE
  2121.     charlit '?'
  2122.     ctok    EMIT
  2123.     ctok    SPACE
  2124.     literal    -13
  2125.     ctok    THROW
  2126.  
  2127. ; Can't use our name header macros with this one!
  2128.     linkme    flinkptr
  2129.     countcell    1
  2130.     db    "'",0        ; -- xt | abort
  2131.     align    4        ; CORE
  2132. fw_TICK:
  2133.     ctok    NEST
  2134.     ctok    BL
  2135.     ctok    WORD
  2136.     ctok    FIND
  2137.     ctok    ZEROEQ
  2138.     compif    tick1
  2139.     ctok    UNFOUND
  2140. tick1:    ctok    UNNEST
  2141.  
  2142. ; Can't use our name header macros with this one!
  2143.     linkme    flinkptr
  2144.     countcell    <3 or immedMask>
  2145.     db    '[',0,"'",0,']',0    ; -- | abort
  2146.     align    4            ; CORE
  2147. fw_BRACKETTICK:
  2148.     ctok    NEST
  2149.     ctok    STATEABORT
  2150.     ctok    TICK
  2151.     ctok    LITERAL
  2152.     ctok    UNNEST
  2153.  
  2154.     fname    <ALIGN>        ; --
  2155.     ctok    NEST        ; CORE
  2156.     literal    cell        ; -- 4
  2157.     ctok    HERE        ; -- 4 addr
  2158.     literal    cell-1        ; -- 4 addr 3
  2159.     ctok    AND        ; -- 4 xx
  2160.     ctok    DUP        ; -- 4 xx xx
  2161.     compif    align1        ; -- 4 xx    "extra bits" indicating cell alignment?
  2162.     ctok    MINUS        ; -- n        address now aligned, but a cell short
  2163.     ctok    ALLOT        ; --        now it's ok
  2164.     ctok    EXIT
  2165. align1:    ctok    TWO_DROP    ; 4 xx --
  2166.     ctok    UNNEST
  2167.         
  2168.     fname    <ALIGNED>    ; addr -- a-addr
  2169.     ctok    NEST        ; CORE
  2170.     ctok    DUP        ; -- a a
  2171.     literal    cell-1        ; -- a a n
  2172.     ctok    AND        ; -- a x
  2173.     ctok    DUP        ; -- a x x
  2174.     compif    aligned1    ; -- a x    "extra bits" indicating cell alignment?
  2175.     ctok    MINUS        ; -- a-a'    address now aligned, but a cell short
  2176.     literal    cell        ; -- a-a' n
  2177.     ctok    PLUS        ; -- a-a
  2178.     ctok    EXIT
  2179. aligned1:            ; -- a-a x    no "extra bits"
  2180.     ctok    DROP        ; -- a-a
  2181.     ctok    UNNEST
  2182.  
  2183.     fname    <ALLOT>        ; n --
  2184.     dd    allot        ; CORE
  2185. allot:    pop    eax
  2186.     add    datap[dp],eax
  2187.     next
  2188.  
  2189.     fnamemanque    <CELL+>    ; a-addr1 -- a-addr2
  2190. fw_CELL_PLUS:            ; CORE
  2191.     dd    cell_plus
  2192. cell_plus:
  2193.     add    DWORD PTR [esp],cell
  2194.     next
  2195.  
  2196.     fname    <CELLS>        ; n1 -- n2
  2197.     ctok    NEST        ; CORE
  2198.     literal    cell
  2199.     ctok    STAR
  2200.     ctok    UNNEST
  2201.  
  2202.     fnamemanque    <FORTH-WORDLIST>    ; -- wid
  2203. fw_FWORDLIST:            ; SEARCH
  2204.     ctok    DOKWORDLIST
  2205.     dd    flinkp        ; pointer to data address of of last word added to list
  2206.     dd    0        ; token of next wordlist in link
  2207.  
  2208.     fnamemanque    <INTERNALS-WORDLIST>    ; -- wid
  2209. fw_ZWORDLIST:            ; Implementation
  2210.     ctok    DOKWORDLIST
  2211.     dd    zlinkp        ; pointer to data address of of last word added to list
  2212.     ctok    FWORDLIST    ; token of next wordlist in link
  2213.  
  2214.     fnamemanque    <NONSTANDARD-WORDLIST>    ; -- wid
  2215. fw_NWORDLIST:            ; Implementation
  2216.     ctok    DOKWORDLIST
  2217.     dd    nlinkp        ; pointer to data address of of last word added to list
  2218.     ctok    ZWORDLIST    ; token of next wordlist in link
  2219.  
  2220.     fnamemanque    <SYSTEM-WORDLIST>    ; -- wid
  2221. fw_SWORDLIST:            ; Implementation
  2222.     ctok    DOKWORDLIST
  2223.     dd    slinkp        ; pointer to data address of of last word added to list
  2224.     ctok    NWORDLIST    ; token of next wordlist in link
  2225.  
  2226.     fname    <FORTH>        ; --
  2227.     ctok    NEST        ; SEARCH EXT
  2228.     ctok    GET_ORDER
  2229.     ctok    QDUP
  2230.     compif    forth1
  2231.     ctok    NIP
  2232.     ctok    FWORDLIST
  2233.     ctok    SWAP
  2234.     ctok    SET_ORDER
  2235.     ctok    EXIT
  2236. forth1:    ctok    FWORDLIST
  2237.     literal    1
  2238.     ctok    SET_ORDER
  2239.     ctok    UNNEST
  2240.     
  2241.     fnamemanque    <SET-CURRENT>    ; wid --
  2242. fw_SET_CURRENT:                ; SEARCH
  2243.     docode
  2244.     pop    DWORD PTR current[dp]    ; store wid to the current compilation wordlist variable
  2245.     next
  2246.  
  2247.     fnamemanque    <GET-CURRENT>    ; -- wid
  2248. fw_GET_CURRENT:                ; SEARCH
  2249.     dd    get_current
  2250. get_current:
  2251.     push    DWORD PTR current[dp]
  2252.     next
  2253.  
  2254.     fnamemanque    <SET-ORDER>    ; wid1 .. widn n --
  2255. fw_SET_ORDER:                ; SEARCH
  2256.     ctok    NEST
  2257.     ctok    DUP
  2258.     literal    searchOrderSize
  2259.     ctok    GREATER            ; no bogus indices, please!
  2260.     literal    -49            ; search order overflow THROW
  2261.     ctok    AND
  2262.     ctok    THROW
  2263.     ctok    DUP
  2264.     ctok    ZEROLT
  2265.     literal    -50            ; search order underflow THROW
  2266.     ctok    AND
  2267.     ctok    THROW
  2268.     literal    searchOrderSize
  2269.     literal    0
  2270.     compqdo    set_order1
  2271. set_order0:                ; loop clearing search order
  2272.     ctok    FALSE
  2273.     literal    searchOrder
  2274.     ctok    I
  2275.     ctok    CELLS
  2276.     ctok    PLUS
  2277.     ctok    STORE
  2278.     comploop    set_order0
  2279. set_order1:
  2280.     literal    0
  2281.     compqdo    set_order3        ; ?DO since 0 is a legit argument
  2282. set_order2:                ; loop filling cells, (if any
  2283.     literal    searchOrder
  2284.     ctok    I
  2285.     ctok    CELLS
  2286.     ctok    PLUS
  2287.     ctok    STORE
  2288.     comploop    set_order2
  2289. set_order3:
  2290.     ctok    UNNEST
  2291.  
  2292.     fname    <WORDLIST>    ; -- wid
  2293.     ctok    NEST        ; SEARCH
  2294.     literal    unnamedHdr
  2295.     ctok    ABSTODATA
  2296.     ctok    COUNT
  2297.     ctok    NAMEWORDLIST
  2298.     ctok    UNNEST
  2299.  
  2300.     nname    <NAMEWORDLIST>    ; c-addr u -- wid
  2301.     ctok    NEST
  2302.     ctok    HEADER        ; make "UNNAMED" header ...
  2303.     ctok    LINKIT        ; ... and link it in current wordlist
  2304.     ctok    DP
  2305.     ctok    FETCH        ; save dictionary pointer to convert to token for this wordlist
  2306.     ctok    DOLIT
  2307.     ctok    DOKWORDLIST    ; embed wordlist engine
  2308.     ctok    COMPCOMMA
  2309.     ctok    HERE        ; pointer to the link pointer for this wordlist
  2310.     ctok    COMPCOMMA
  2311.     literal    1
  2312.     ctok    CELLS
  2313.     ctok    ALLOT        ; allot storage for that link pointer
  2314.     literal    wllink
  2315.     ctok    FETCH
  2316.     ctok    COMPCOMMA    ; compile back pointer to previous wordlist
  2317.     ctok    MAKETOKEN    ; convert that dictionary pointer sitting on the stack to a user token
  2318.     ctok    DUP        ; save copy
  2319.     literal    wllink
  2320.     ctok    STORE        ; store that token in the wordlist link pointer as last wordlist added
  2321.     ctok    EXECUTE        ; return own WID
  2322.     ctok    UNNEST
  2323.  
  2324.     nname    <WORDLISTS>    ; --
  2325.     ctok    NEST        ; Not in Standard
  2326.     ctok    CR
  2327.     literal    wlHdr
  2328.     ctok    ABSTODATA
  2329.     ctok    COUNT
  2330.     ctok    TYPE
  2331.     literal    wllink
  2332. wordlists1:
  2333.     ctok    FETCH
  2334.     ctok    QDUP
  2335.     compif    wordlists2
  2336.     ctok    TOKENTODATA
  2337.     ctok    DUP
  2338.     ctok    DOT_WID
  2339.     ctok    SPACE
  2340.     literal    2
  2341.     ctok    CELLS
  2342.     ctok    PLUS
  2343.     compelse    wordlists1
  2344. wordlists2:
  2345.     ctok    CR
  2346.     ctok    UNNEST
  2347.  
  2348.     fname    <WORDS>    ; --
  2349.     ctok    NEST    ; TOOLKIT
  2350.     ctok    CR
  2351.     literal    searchOrder
  2352.     ctok    FETCH        ; -- wid
  2353.     ctok    FETCH        ; -- addr of thread
  2354. words1:
  2355.     ctok    FETCH        ; -- link-token
  2356.     ctok    QDUP        ; is it null
  2357.     compif    words2        ; if null, we're done
  2358.     ctok    DUP        ; -- lt lt
  2359.     ctok    DOT_WORD    ; -- lt
  2360.     ctok    TOKENTODATA    ; -- a-addr
  2361.     compelse    words1
  2362. words2:
  2363.     ctok    CR
  2364.     ctok    UNNEST
  2365.  
  2366.     fnamemanque    <GET-ORDER>    ; ( -- wid1 .. widn n)
  2367. fw_GET_ORDER:                ; SEARCH
  2368.     ctok    NEST
  2369.     literal    0            ; holder, -- 0
  2370.     literal    searchOrderSize        ; -- 0 n
  2371.     literal    0            ; -- 0 n 0
  2372.     compqdo    get_order2
  2373. get_order0:                ; -- 0
  2374.     literal    searchOrder        ; -- 0 a-addr
  2375.     ctok    I            ; -- 0 a-addr n
  2376.     ctok    CELLS            ; -- 0 a-addr n'
  2377.     ctok    PLUS            ; -- 0 a-addr'
  2378.     ctok    FETCH            ; -- 0 wid
  2379.     ctok    ZEROEQ            ; -- 0 flag
  2380.     compif    get_order1
  2381.     ctok    LEAVE            ; -- 0
  2382. get_order1:
  2383.     ctok    ONE_PLUS        ; -- 0+1
  2384.     comploop    get_order0
  2385. get_order2:
  2386.     ctok    DUP            ; -- index index
  2387.     literal    0            ; -- index index 0
  2388.     compqdo    get_order4        
  2389. get_order3:                ; -- index
  2390.     ctok    DUP            ; -- index index
  2391.     ctok    ONE_MINUS        ; -- index index'
  2392.     ctok    CELLS            ; -- index n
  2393.     literal    searchOrder        ; -- index n a-addr
  2394.     ctok    PLUS            ; -- index a-addr'(last cell with a valid wid in it)
  2395.     ctok    I
  2396.     ctok    CELLS    
  2397.     ctok    MINUS            ; -- index a-addr''
  2398.     ctok    FETCH            ; -- index wid
  2399.     ctok    SWAP            ; -- wid index
  2400.     comploop    get_order3
  2401. get_order4:
  2402.     ctok    UNNEST
  2403.  
  2404.     fname    <ORDER>            ; --
  2405.     ctok    NEST            ; SEARCH EXT
  2406.     ctok    CR
  2407.     literal    orderMsg0
  2408.     ctok    ABSTODATA
  2409.     literal    orderMsg0Len
  2410.     ctok    TYPE            ; --         display text
  2411.     ctok    GET_ORDER
  2412.     literal    0
  2413.     compqdo    order1
  2414. order0:    ctok    DOT_WID            ; --         print each wid and its name
  2415.     comploop    order0
  2416. order1:    ctok    CR
  2417.     literal    orderMsg1
  2418.     ctok    ABSTODATA
  2419.     literal    orderMsg1Len
  2420.     ctok    TYPE            ; --         display text
  2421.     ctok    GET_CURRENT
  2422.     ctok    QDUP
  2423.     compif    order2
  2424.     ctok    DOT_WID            ; --         print each wid
  2425. order2:    ctok    CR
  2426.     ctok    UNNEST
  2427.  
  2428.     nnamemanque    <.NAME>    ; c-addr --
  2429. fw_DOT_NAME:            ; Implementation
  2430.     ctok    NEST
  2431.     ctok    COUNT
  2432.     literal    allNameMasks
  2433.     ctok    INVERT
  2434.     ctok    AND
  2435.     ctok    TYPE
  2436.     ctok    SPACE
  2437.     ctok    UNNEST
  2438.  
  2439.     nnamemanque    <.WID>    ; wid --
  2440. fw_DOT_WID:            ; Implementation
  2441.     ctok    NEST
  2442.     ctok    DUP
  2443.     ctok    EXETONAME
  2444.     ctok    DOT_NAME
  2445.     ctok    U_DOT
  2446.     ctok    UNNEST
  2447.  
  2448.     znamemanque    <.WORD>    ; link-token --
  2449. fw_DOT_WORD:            ; Implementation
  2450.     ctok    NEST
  2451.     ctok    TOKENTODATA
  2452.     ctok    LINKTONAME
  2453.     ctok    DOT_NAME
  2454.     ctok    UNNEST
  2455.  
  2456.     fname    <ALSO>        ; --
  2457.     ctok    NEST        ; SEARCH EXT
  2458.     ctok    GET_ORDER
  2459.     ctok    OVER
  2460.     ctok    SWAP
  2461.     ctok    ONE_PLUS
  2462.     ctok    SET_ORDER
  2463.     ctok    UNNEST
  2464.  
  2465.     fname    <PREVIOUS>    ; --
  2466.     ctok    NEST        ; SEARCH EXT
  2467.     ctok    GET_ORDER
  2468.     ctok    DUP
  2469.     literal    2
  2470.     ctok    LESS
  2471.     literal    -50
  2472.     ctok    AND
  2473.     ctok    THROW        ; search order underflow THROW
  2474.     ctok    NIP
  2475.     ctok    ONE_MINUS
  2476.     ctok    SET_ORDER
  2477.     ctok    UNNEST
  2478.  
  2479.     fname    <ONLY>        ; --
  2480.     ctok    NEST        ; SEARCH EXT
  2481.     ctok    FWORDLIST
  2482.     literal    1
  2483.     ctok    SET_ORDER
  2484.     ctok    UNNEST
  2485.  
  2486.     fname    <DEFINITIONS>    ; --
  2487.     ctok    NEST        ; SEARCH EXT
  2488.     literal    searchOrder
  2489.     ctok    FETCH
  2490.     ctok    SET_CURRENT
  2491.     ctok    UNNEST
  2492.  
  2493.     fnamemanque    <SEARCH-WORDLIST>    ; c-addr u wid -- 0 | xt 1 | xt -1)
  2494. fw_SEARCH_WL:                    ; SEARCH
  2495.     ctok    NEST
  2496.     ctok    FETCH                ; wid is a data address, which address points to address ...
  2497.     ctok    FETCH                ; .. of data location holding last link in the wordlist
  2498. search_wl0:
  2499.     ctok    DUP                ; is link to zero (end of list)
  2500.     compif    search_wl_fail            ; No, it's a real link
  2501.     ctok    TO_R                ; save copy of ltoken
  2502.     ctok    TWO_DUP                ; -- c-a u c-a u    R: -- ltoken
  2503.     ctok    R_FETCH                ; -- c-a u c-a u ltoken    R: -- ltoken
  2504.     ctok    TOKENTODATA            ; -- c-a u c-a u a-a    R: -- ltoken
  2505.     ctok    LINKTONAME            ; -- c-a1 u c-a1 u c-a2    R: -- ltoken
  2506.     ctok    DUP
  2507.     ctok    TO_R                ; -- c-a1 u c-a1 u c-a2    R: -- ltoken name-address    
  2508.     ctok    COUNT                ; -- c-a1 u1 c-a1 u1 c-a2 u2+mask
  2509.     literal    allNameMasks            ; unmask name count byte
  2510.     ctok    INVERT
  2511.     ctok    AND
  2512.     ctok    COMPARE                ; -- c-a1 u1 0|1|-1    R: -- ltoken name-address
  2513.     ctok    ZEROEQ                ; -- c-a1 u1 flag    R: -- ltoken name-address
  2514.     compif    search_wl4            ; Zero? We found it
  2515.     ctok    TWO_DROP            ; --            R: -- ltoken name-address
  2516.     ctok    R_FROM                ; -- name-address    R: -- ltoken
  2517.     ctok    C_FETCH                ; -- count-word+mask    R: -- ltoken
  2518.     literal    immedMask
  2519.     ctok    AND                ; -- bit        R: -- ltoken
  2520.     compif    search_wl1
  2521.     literal    1                ; -- 1            R: -- ltoken
  2522.     compelse    search_wl2
  2523. search_wl1:                    ; -- -1            R: -- ltoken
  2524.     literal    -1
  2525. search_wl2:
  2526.     ctok    R_FROM                ; -- n ltoken
  2527.     ctok    DUP                ; -- n ltoken ltoken
  2528.     ctok    TOKENTODATA            ; -- n ltoken a-addr(link)
  2529.     ctok    LINKTOEXE            ; -- n ltoken a-addr'
  2530.     ctok    DATATOABS            ; -- n ltoken abs-addr
  2531.     ctok    SWAP                ; -- n a-addr' ltoken 
  2532.     ctok    USERTOKENQ            ; -- n a-addr' flag
  2533.     compif    search_wl3            ; -- is this in user dictionary?
  2534.     ctok    ABSTOCODE            ; yes, convert to code token
  2535.     ctok    MAKETOKEN            ; -- n xt
  2536. search_wl3:                    ; -- no, abs address is valid xt for kernel words
  2537.     ctok    SWAP                ; -- xt 1|-1
  2538.     ctok    EXIT
  2539. search_wl4:                    ; didn't match, -- c-a1 u1    R: -- ltoken name-address
  2540.     ctok    R_FROM
  2541.     ctok    DROP                ; -- c-a1 u1        R: -- ltoken
  2542.     ctok    R_FROM                ; -- c-a1 u1 ltoken    R: --
  2543.     ctok    TOKENTODATA            ; -- c-a u a-addr
  2544.     ctok    FETCH                ; -- c-a u next-link-tok
  2545.     compelse    search_wl0        ; try again
  2546. search_wl_fail:                    ; ran out of links, -- c-a u ltoken
  2547.     ctok    DROP
  2548.     ctok    TWO_DROP                ; --
  2549.     ctok    FALSE                ; -- 0
  2550.     ctok    UNNEST
  2551.  
  2552.     fname    <HERE>        ; -- addr
  2553.     dd    here        ; CORE
  2554. here:    push    [dp+datap]
  2555.     next
  2556.  
  2557. ; Convert token such as link pointer or execution token to data-relative address
  2558.     zname    <TOKENTODATA>    ; linkt|xt -- a-addr
  2559.     ctok    NEST        ; Implementation
  2560.     ctok    DUP
  2561.     ctok    USERTOKENQ
  2562.     compif    t_to_data1
  2563.     ctok    DETOKEN
  2564.     ctok    CODETODATA
  2565.     ctok    EXIT
  2566. t_to_data1:
  2567.     ctok    ABSTODATA
  2568.     ctok    UNNEST
  2569.  
  2570. ; All these convert from one data-relative address to another. LINK is the link address. EXE is the address
  2571. ; which is represented by the execution token for the word. NAME is the count word address at the head of
  2572. ; the name field, not the FFFF word before it.
  2573.  
  2574.     zname    <EXETOLINK>    ; a-addr1 -- a-addr2
  2575.     ctok    NEST        ; Implementation
  2576.     ctok    EXETONAME
  2577.     ctok    NAMETOLINK
  2578.     ctok    UNNEST
  2579.  
  2580.     zname    <LINKTOEXE>    ; a-addr1 -- a-addr2
  2581.     ctok    NEST        ; Implementation
  2582.     ctok    LINKTONAME
  2583.     ctok    NAMETOEXE
  2584.     ctok    UNNEST
  2585.  
  2586.     zname     <NAMETOLINK>    ; c-addr -- a-addr
  2587.     ctok    NEST        ; Implementation
  2588.     literal    1
  2589.     ctok    CHARS
  2590.     ctok    MINUS        ; back past the FFFF marker word
  2591.     literal    1
  2592.     ctok    CELLS
  2593.     ctok    MINUS        ; back to head of link field
  2594.     ctok    UNNEST
  2595.  
  2596.     zname    <LINKTONAME>    ; a-addr -- c-addr
  2597.     ctok    NEST        ; Implementation
  2598.     literal    1
  2599.     ctok    CELLS
  2600.     ctok    PLUS        ; past link field
  2601.     literal    1
  2602.     ctok    CHARS
  2603.     ctok    PLUS        ; past the FFFF marker word
  2604.     ctok    UNNEST
  2605.  
  2606.     zname    <NAMETOEXE>    ; c-addr -- a-addr
  2607.     ctok    NEST
  2608.     ctok    COUNT
  2609.     literal    allNameMasks
  2610.     ctok    INVERT
  2611.     ctok    AND        ; mask out all "funny" bits in count word
  2612.     ctok    CHARS
  2613.     ctok    PLUS
  2614.     ctok    ALIGNED
  2615.     ctok    UNNEST
  2616.  
  2617.     zname    <EXETONAME>    ; a-addr -- c-addr
  2618.     ctok    NEST
  2619. exetoname1:
  2620.     literal    1
  2621.     ctok    CHARS
  2622.     ctok    MINUS
  2623.     ctok    DUP
  2624.     ctok    C_FETCH
  2625.     literal    UniNotAChar
  2626.     ctok    EQUAL
  2627.     compuntil    exetoname1
  2628.     ctok    CHAR_PLUS
  2629.     ctok    UNNEST
  2630.     
  2631. ;--( Interpreter )
  2632.  
  2633.     fname    <BLK>        ; -- a-addr
  2634.     ctok    DOCONST        ; CORE
  2635.     dd    var_blk
  2636.  
  2637.  
  2638.     fname    <FIND>        ; ( c-addr -- c-addr 0 | xt 1 | xt -1 )
  2639.     ctok    NEST        ; CORE
  2640.     ctok    DUP        ; -- $addr
  2641.     ctok    C_FETCH        ; -- $addr u
  2642.     compif    _4find        ; IF the count is non-zero
  2643.     literal    searchOrder    ; -- $addr addr
  2644.     literal    cell        ; -- $addr addr n
  2645.     ctok    MINUS        ; back up to one cell before beginning of search order array
  2646.     ctok    SWAP        ; ptr-to-wid $addr
  2647.     ctok    FALSE        ; ptr-to-wid $addr 0(place holder for DROP of SEARCH-WORDLIST result in loop)
  2648.     ctok    FALSE        ; ptr-to-wid $addr 0(place holder for DROP of DUPed flag SEARCH-WORDLIST in loop)
  2649.     literal    searchOrderSize    ; number of vocabularies in search order
  2650.     literal    0
  2651.     compdo    _3find        ; loop until success or run out of search order
  2652. _0find:                ; -- ptr-to-wid $addr 0 0
  2653.     ctok    TWO_DROP    ; -- ptr-to-wid $addr
  2654.     literal    cell        ; -- ptr-to-wid $addr n
  2655.     ctok    ROT        ; -- $addr n ptr-to-wid
  2656.     ctok    PLUS        ; -- ptr-to-wid $addr
  2657.     ctok    SWAP        ; -- ptw $addr
  2658.     ctok    OVER        ; -- ptr-to-wid $addr ptr-to-wid
  2659.     ctok    FETCH        ; -- ptw $addr wid|0
  2660.     ctok    QDUP        ; we may have reached end of search order
  2661.     compif    _1find        ; -- ptw $addr wid ,valid vocabulary pointer
  2662.     ctok    OVER        ; -- ptw $addr wid $addr
  2663.     ctok    COUNT        ; -- ptw $addr wid c-addr u
  2664.     ctok    ROT        ; -- ptw $addr c-addr u wid
  2665.     ctok    SEARCH_WL    ; -- ptw $a1 [[ 0 ]|[ exetok [ -1|1 ]]]
  2666.     ctok    DUP        ; -- ptw $a1 [[ 0 0 ]|[ exetok [ -1|1 ] [-1|1]]]
  2667.     ctok    ZEROEQ
  2668.     compif    yfind
  2669.     ctok    DUP        ; -- ptw $a1 x1 x2
  2670. yfind:    compelse    _2find    ; NULL in CONTEXT at this entry
  2671. _1find:                ; -- ptw $addr ,invalid wid ptr, end of order
  2672.     ctok    NIP        ; -- $addr
  2673.     ctok    FALSE        ; -- $addr 0
  2674.     ctok    UNLOOP        ; -- $addr 0
  2675.     ctok    EXIT        ; -- c-addr 0
  2676. _2find:                ; -- ptw $addr x1 x2
  2677.     ctok    DUP        ; -- ptw $addr x1 x2 x2
  2678.     compif    xfind        ; -- ptw $addr x [-1|0|1]
  2679.     ctok    LEAVE        ; -- ptw $a1 x x
  2680. xfind:    comploop    _0find
  2681. _3find:                ; -- ptw $a1 xt flag1
  2682.     ctok    ROT
  2683.     ctok    DROP        ; -- ptw xt flag
  2684.     ctok    ROT
  2685.     ctok    DROP        ; -- xt flag
  2686.     ctok    EXIT        ; -- xt flag
  2687. _4find:                ; -- $addr the string was null
  2688.     ctok    TRUE
  2689.     literal    endq        ; var that indicates end of input
  2690.     ctok    STORE
  2691.     ctok    FALSE        ; -- c-addr 0
  2692.     ctok    UNNEST
  2693.  
  2694.     nnamemanque    <?STACK>        ; i*j -- i*j | -
  2695. fw_QSTACK:
  2696.     ctok    NEST        ; implementation
  2697.     ctok    SP0
  2698.     ctok    FETCH        ; original stack pointer    
  2699.     ctok    SP_FETCH    ; current stack pointer
  2700.     literal    cell
  2701.     ctok    PLUS        ; adjusted for presence of orig. stack ptr. on stack
  2702.     ctok    U_LESS        ; has stack underflowed?
  2703.     compif    qstack1
  2704.     literal    -4        ; Stack Underflow Throw
  2705.     ctok    THROW
  2706. qstack1:
  2707.     ctok    UNNEST        ; no, continue
  2708.  
  2709.     zname    <INTERPRET>    ; ( --)
  2710.     ctok    NEST        ; Not in Standard
  2711. _0inter:            ; Begin
  2712.     ctok    QSTACK        ; --
  2713.     ctok    BL
  2714.     ctok    WORD
  2715.     ctok    FIND        ; -- [ 'word 0 ] | [ cfa 1|-1 ]
  2716.     ctok    QDUP        ; -- [ 'word 0 ] | [ cfa 1|-1 1|-1]
  2717.     compif    _1inter        ; -- cfa 1|-1
  2718.     ctok    STATE
  2719.     ctok    FETCH        ; -- cfa 1|-1 flag
  2720.     compif    _9inter        ; compiling
  2721.     ctok    ZEROLT        ; non-immediate?
  2722.     compif    _8inter        ; yes, compile it
  2723.     ctok    COMPCOMMA    ; --
  2724.     compelse    _0inter    ; --
  2725. _8inter:
  2726.     ctok    EXECUTE        ; --
  2727.     compelse    _0inter    ; --
  2728. _9inter:
  2729.     ctok    DROP        ; -- cfa  ,interpreting
  2730.     ctok    EXECUTE        ; --   ,execute found word
  2731.     literal    endq
  2732.     ctok    FETCH        ; -- t|f ,see if input stream exhausted
  2733.     compif    _0inter        ; -- loop if not exhausted
  2734.     ctok    EXIT        ; -- ,exhausted? exit INTERPRET
  2735. _1inter:
  2736.     literal    endq        ; input stream exhausted?
  2737.     ctok    FETCH        ; -- c-addr flag
  2738.     compif    _5inter        ; if yes we're done, else we might be looking at a number
  2739.     ctok    DROP        ; discard c-addr
  2740.     ctok    EXIT        ; exit INTERPRET
  2741. _5inter:
  2742.     ctok    COUNT        ; -- c-addr1 u1
  2743.     ctok    NUMBER        ; -- d flag
  2744.     ctok    ZEROEQ        ; -- d t|f
  2745.     compif    _zinter        ; wasn't a number in current base, fail
  2746.     ctok    UNFOUND        ; show offending lexical item with "?"
  2747. _zinter:
  2748.     ctok    DPL        ; -- d a-addr        check for double precision
  2749.     ctok    FETCH        ; -- d [ n | -1 ]
  2750.     ctok    TRUE        ; -- d [ n | -1 ] TRUE
  2751.     ctok    EQUAL        ; -- d t|f
  2752.     compif    _6inter        ; -- ud2
  2753.     ctok    DROP        ; -- u  ,drop hi-order if not double precis
  2754.     ctok    STATE        ; -- u addr
  2755.     ctok    FETCH        ; -- u flag
  2756.     compif    _2inter        ; -- u
  2757.     ctok    LITERAL        ; --
  2758.     compelse    _2inter    ; -- u
  2759. _6inter:
  2760.     ctok    STATE        ; -- ud2 addr
  2761.     ctok    FETCH        ; -- ud2 flag
  2762.     compif    _2inter        ; -- ud2
  2763.     ctok    TWO_LITERAL    ; --
  2764. _2inter:                ; Then
  2765.     literal    endq
  2766.     ctok    FETCH        ; -- flag
  2767.     compuntil    _0inter    ; Until
  2768.     ctok    UNNEST
  2769.  
  2770.     fname    <EVALUATE>    ; i*x c-addr u -- j*x
  2771.     ctok    NEST
  2772.     ctok    BLK        ; Save input on return stack
  2773.     ctok    FETCH
  2774.     ctok    TO_R
  2775.     ctok    TIB
  2776.     ctok    TO_R
  2777.     ctok    NUMTIB
  2778.     ctok    FETCH
  2779.     ctok    TO_R
  2780.     ctok    TO_IN
  2781.     ctok    FETCH
  2782.     ctok    TO_R
  2783.     ctok    SOURCE_ID
  2784.     ctok    FETCH
  2785.     ctok    TO_R
  2786.     literal    endq
  2787.     ctok    FETCH
  2788.     ctok    TO_R
  2789.     ctok    FALSE
  2790.     literal    endq
  2791.     ctok    STORE
  2792.     ctok    NUMTIB
  2793.     ctok    STORE
  2794.     ctok    TICK_TIB
  2795.     ctok    STORE
  2796.     literal    -1
  2797.     ctok    SOURCE_ID
  2798.     ctok    STORE        ; -- i*x c-addr u    R: -- BLK TIB #TIB >IN SOURCE-ID
  2799.     ctok    FALSE
  2800.     ctok    BLK
  2801.     ctok    STORE
  2802.     ctok    FALSE
  2803.     ctok    TO_IN
  2804.     ctok    STORE
  2805.     ctok    INTERPRET    ; -- j*x        R: -- BLK TIB #TIB >IN SOURCE-ID
  2806.     ctok    R_FROM        ; Restore input spec
  2807.     literal    endq
  2808.     ctok    STORE
  2809.     ctok    R_FROM    
  2810.     ctok    SOURCE_ID
  2811.     ctok    STORE
  2812.     ctok    R_FROM
  2813.     ctok    TO_IN
  2814.     ctok    STORE
  2815.     ctok    R_FROM
  2816.     ctok    NUMTIB
  2817.     ctok    STORE
  2818.     ctok    R_FROM
  2819.     ctok    TICK_TIB
  2820.     ctok    STORE
  2821.     ctok    R_FROM
  2822.     ctok    BLK
  2823.     ctok    STORE        ; -- j*x        R: --
  2824.     ctok    UNNEST
  2825.     
  2826.     znamemanque    <(PARSE)>        ; char "ccc<char>" -- c-addr u
  2827. fw_PPARSE:
  2828.     ctok    NEST            ; this one skips leading delims
  2829.     ctok    SOURCE            ; -- ch c-a u   , get TIB or current BLOCK & char count
  2830.     ctok    TO_IN            ; -- ch c-a u a , get addr of current interp inset var
  2831.     ctok    FETCH            ; -- ch c-a u n , get current inset
  2832.     ctok    SLSTRING        ; -- ch c-a' u'
  2833.     ctok    OVER            ; -- ch c-a' u' c-a'    Need a copy to increment >IN
  2834.     ctok    TO_R            ; -- ch c-a' u'        R: -- c-a'
  2835.     ctok    DUP            ; -- ch c-a' u' u'    R: -- c-a'
  2836.     ctok    ZEROGT            ; -- ch c-a' u' t|f    R: -- c-a'
  2837.     compif    _0parse            ; -- ch c-a' u'        R: -- c-a'
  2838.     literal    2            ; -- ch c-a' u' 2    R: -- c-a'
  2839.     ctok    PICK            ; -- ch c-a' u' ch' , copy of delim char R: -- c-a'
  2840.     ctok    SKIP            ; -- ch c-a'' u'' , skip leading delim     R: -- c-a'
  2841. _9parse:
  2842.     ctok    OVER            ; -- ch c-a'' u'' c-a''    R: -- c-a'
  2843.     ctok    TO_R            ; -- ch c-a'' u'' ,save adr of 1st char R: -- c-a' c-a''
  2844.     ctok    ROT            ; -- c-a' u'' ch    R: -- c-a' c-a''
  2845.     ctok    SCAN            ; -- c-a''' u'''    R: -- c-a' c-a''
  2846.     ctok    DROP            ; -- c-a'''        R: -- c-a' c-a''
  2847.     ctok    R_FROM            ; -- c-a''' c-a''    R: -- c-a'
  2848.     ctok    R_FROM            ; -- c-a''' c-a'' c-a'    R: --
  2849.     literal    2            ; -- c-a''' c-a'' c-a' 2
  2850.     ctok    PICK            ; -- c-a''' c-a'' c-a' c-a'''
  2851.     ctok    SWAP            ; -- c-a''' c-a'' c-a''' c-a'
  2852.     ctok    MINUS            ; -- c-a''' c-a'' n=bytes
  2853.     ctok    TWO_SLASH        ; -- c-a''' c-a'' n=chars
  2854.     ctok    ONE_PLUS        ; account for the character itself which was parsed to.
  2855.     ctok    TO_IN            ; -- c-a''' c-a'' n a
  2856.     ctok    PL_STORE        ; -- c-a''' c-a''
  2857.     ctok    TUCK            ; -- c-a'' c-a''' c-a''
  2858.     ctok    MINUS            ; -- c-addr1 bytes
  2859.     ctok    TWO_SLASH        ; -- c-addr1 u=chars
  2860.     compelse    _1parse        ; -- ch c-a u    R: -- c-a
  2861. _0parse:
  2862.     ctok    R_FROM
  2863.     ctok    DROP            ; -- ch c-a u    R: --
  2864.     ctok    DROP            ; -- ch c-a
  2865.     ctok    NIP            ; -- c-a
  2866.     literal    0            ; -- c-a 0
  2867. _1parse:
  2868.     ctok    UNNEST
  2869.  
  2870.     fname    <PARSE>        ; ( char "ccc<char>" -- c-addr u)
  2871.     ctok    NEST        ; CORE EXT, hits on leading delimiters
  2872.     ctok    SOURCE        ; -- ch c-a u   , get TIB or current BLOCK & char count
  2873.     ctok    TO_IN        ; -- ch c-a u a , get addr of current interp inset var
  2874.     ctok    FETCH        ; -- ch c-a u n , get current inset
  2875.     ctok    SLSTRING    ; -- ch c-a' u'
  2876.     ctok    OVER        ; -- ch c-a' u' c-a'    Need a copy to increment >IN
  2877.     ctok    TO_R        ; -- ch c-a' u'        R: -- c-a'
  2878.     ctok    DUP        ; -- ch c-a' u' u'    R: -- c-a'
  2879.     ctok    ZEROGT        ; -- ch c-a' u' t|f    R: -- c-a'
  2880.     compif    _0parse        ; -- ch c-a' u'        R: -- c-a'
  2881.     compelse    _9parse
  2882.  
  2883.     zname    <okPrompt>    ; i*x -- i*x
  2884.     ctok    NEST        ; implementation
  2885.     ctok    DOKDOTQUOTE
  2886.     dd    okPrompt
  2887.     ctok    DEPTH
  2888.     ctok    DOT
  2889.     ctok    UNNEST
  2890.  
  2891.     nnamemanque    <..>    ; i*x --
  2892. fw_DOTDOT:
  2893.     ctok    NEST
  2894.     ctok    DEPTH
  2895.     literal    0
  2896.     compqdo    dotdot2
  2897. dotdot1:
  2898.     ctok    U_DOT
  2899.     comploop    dotdot1
  2900. dotdot2:
  2901.     ctok    UNNEST
  2902.  
  2903.     fname    <QUIT>        ; ( --) ( R: i*x --)
  2904.     ctok    NEST        ; CORE
  2905.     literal    FALSE
  2906.     ctok    BLK        ; Not BLOCK input
  2907.     ctok    STORE
  2908.     literal    FALSE
  2909.     ctok    SOURCE_ID    ; Indicate keyboard input
  2910.     ctok    STORE
  2911.     literal    FALSE
  2912.     ctok    NUMTIB        ; indicate that input stream is empty
  2913.     ctok    STORE
  2914.     literal    FALSE
  2915.     ctok    TO_IN        ; indicate that input stream is unparsed
  2916.     ctok    STORE
  2917.     literal    FALSE
  2918.     ctok    STATE        ; set STATE to interpret
  2919.     ctok    STORE
  2920.     literal    FALSE
  2921.     literal    inDefinition    ; we're not in the middle of a : or :NONAME
  2922.     ctok    STORE
  2923. _1quit:                ; this is a "begin"
  2924.     ctok    CR        ; ye olde CR each Forth QUIT
  2925.     literal    rpzero        ; zero the return stack
  2926.     ctok    FETCH
  2927.     ctok    RP_STORE    ; init the RP stack
  2928.     ctok    FIRSTCATCH    ; set up initial catch frame
  2929.     literal    FALSE
  2930.     literal    endq
  2931.     ctok    STORE        ; reset end-of-input var
  2932.     ctok    REFILL        ; get a line of input
  2933.     compif    _1quit        ; loop back if no input line
  2934.     ctok    INTERPRET    ; execute it
  2935.     ctok    STATE        ; check STATE
  2936.     ctok    FETCH
  2937.     ctok    ZEROEQ
  2938.     compif    _2quit
  2939.     ctok    okPrompt    ; say "ok " if interpreting
  2940. _2quit:  compelse    _1quit    ; and this is an "Again"
  2941.  
  2942. ;!!!***!!! Needs to be finished when File loading support is added.
  2943.     fname    <SOURCE>    ; -- c-addr u
  2944.     ctok    NEST        ; CORE
  2945.     ctok    BLK
  2946.     ctok    FETCH
  2947.     ctok    QDUP
  2948.     compif    source1
  2949.     ctok    BLOCK
  2950.     literal    blockSize
  2951.     ctok    EXIT
  2952. source1:
  2953. ;    ctok    SOURCE_ID
  2954. ;    ctok    FETCH
  2955. ;    ...
  2956.     ctok    TIB
  2957.     ctok    NUMTIB
  2958.     ctok    FETCH
  2959.  
  2960.     ctok    UNNEST
  2961.     
  2962.     fnamemanque    <SOURCE-ID>    ; -- a-addr
  2963. fw_SOURCE_ID:
  2964.     ctok    DOCONST            ; CORE
  2965.     dd    var_srcid
  2966.  
  2967.     fname    <TIB>        ; -- c-addr
  2968.     ctok    NEST        ; CORE EXT
  2969.     ctok    TICK_TIB
  2970.     ctok    FETCH
  2971.     ctok    UNNEST
  2972.  
  2973. ; Can't use our name header macros with this one!
  2974.     linkme    nlinkptr
  2975.     countcell    4
  2976.     db    "'",0,'T',0,'I',0,'B',0    ; -- a-addr
  2977.     align    4            ; Not in Standard
  2978. fw_TICK_TIB:
  2979.     ctok    DOCONST    
  2980.     dd    var_tib
  2981.  
  2982.     fnamemanque    <#TIB>    ; -- c-addr
  2983. fw_NUMTIB:
  2984.     ctok    DOCONST        ; CORE EXT
  2985.     dd    var_numtib
  2986.  
  2987. ; Can't use our name header macros with this one!
  2988.     linkme    flinkptr
  2989.     countcell    3
  2990.     db    '>',0,'I',0,'N',0    ; -- a-addr
  2991.     align    4            ; CORE
  2992. fw_TO_IN:
  2993.     ctok    DOCONST
  2994.     dd    var_to_in
  2995.  
  2996.     fname    <REFILL>    ; -- flag
  2997.     ctok    NEST        ; CORE EXT
  2998.     ctok    SOURCE_ID    ; check source of input
  2999.     ctok    FETCH
  3000.     literal    -1
  3001.     ctok    EQUAL        ; if it's EVALUATE, exit FALSE
  3002.     compif    refill1
  3003.     ctok    FALSE
  3004.     ctok    EXIT
  3005. refill1:
  3006.     ctok    BLK
  3007.     ctok    FETCH        ; -- u
  3008.     ctok    QDUP        ; -- u u | o
  3009.     compif    refill2        ; we get input from the next BLOCK
  3010.     ctok    ONE_PLUS    ; -- u'
  3011.     ctok    DUP        ; -- u' u'
  3012.     ctok    BLK        ; -- u' u' a-addr
  3013.     ctok    STORE        ; -- u'
  3014.     ctok    FALSE        ; Reset interpreter values
  3015.     ctok    TO_IN
  3016.     ctok    STORE
  3017.     ctok    FALSE
  3018.     literal    endq
  3019.     ctok    STORE
  3020.     ctok    INVALIDBLOCK    ; -- flag, TRUE if invalid block number
  3021.     ctok    ZEROEQ        ; -- flag, correct sense for REFILL's return
  3022.     ctok    EXIT
  3023. refill2:            ; We get input from the terminal
  3024.     ctok    FALSE
  3025.     ctok    TO_IN
  3026.     ctok    STORE        ; >IN OFF
  3027.     ctok    FALSE
  3028.     literal    endq
  3029.     ctok    STORE        ; END? OFF
  3030.     ctok    TIB
  3031.     literal    tibsize
  3032.     ctok    ACCEPT        ; Get as many chars as console can return
  3033.     ctok    NUMTIB        ; and store to #TIB
  3034.     ctok    STORE
  3035.     ctok    TRUE
  3036.     ctok    UNNEST
  3037.  
  3038.     fname    <WORD>        ; ( char "ccc<char>" -- c-addr)
  3039.     ctok    NEST        ; CORE
  3040.     ctok    PPARSE        ; -- c-addr u
  3041.     literal    wordBuffer    ; -- c-addr u dest
  3042.     ctok    TWO_DUP        ; -- c-addr u dest u dest
  3043.     ctok    SWAP        ; -- src u dest dest u
  3044.     ctok    ONE_PLUS    ; -- src u dest dest u'        taking the count word into account
  3045.     ctok    CHARS        ; -- src u dest dest n
  3046.     ctok    PLUS        ; -- src u dest c-addr(past end-of-dest)
  3047.     ctok    BL        ; -- src u dest c-addr bl
  3048.     ctok    SWAP        ; -- src u dest bl c-addr
  3049.     ctok    C_STORE        ; -- src u dest         pad string with a blank
  3050.     ctok    PLACE        ; --                install string
  3051.     literal    wordBuffer    ; -- c-addr            return word buffer addr
  3052.     ctok    UNNEST
  3053.  
  3054. ; Can't use our name header macros with this one!
  3055.     linkme    flinkptr
  3056.     countcell    <1 or immedMask>
  3057.     db    '(',0    
  3058.     align    4        ; "ccc<)>" --
  3059. fw_PAREN:            ; CORE
  3060.     ctok    NEST
  3061.     charlit    ')'
  3062.     ctok    PARSE
  3063.     ctok    TWO_DROP
  3064.     ctok    UNNEST
  3065.  
  3066. ; Can't use our name header macros with this one!
  3067.     linkme    flinkptr
  3068.     countcell    <1 or immedMask>
  3069.     db    '\',0    
  3070.     align    4        ; "ccc<eol>" --
  3071. fw_BSLASH:
  3072.     ctok    NEST
  3073.     ctok    BLK
  3074.     ctok    FETCH        ; -- n
  3075.     compif    bslash2
  3076.     ctok    TO_IN
  3077.     ctok    FETCH        ; -- n
  3078.     literal    64
  3079.     ctok    MOD        ; -- mod
  3080.     ctok    QDUP
  3081.     compif    bslash1        ; -- n
  3082.     literal    64
  3083.     ctok    SWAP
  3084.     ctok    MINUS        ; -- diff
  3085.     ctok    TO_IN
  3086.     ctok    PL_STORE    ; --
  3087. bslash1:
  3088.     ctok    EXIT        ; --
  3089. bslash2:
  3090.     ctok    NUMTIB        ; -- a-addr
  3091.     ctok    FETCH        ; -- n
  3092.     ctok    TO_IN
  3093.     ctok    STORE        ; --
  3094.     ctok    UNNEST
  3095.  
  3096. ;--( Implementation Addressing Scheme )
  3097. ; In this terminology, "Code" is the user dictionary offset from register CP,
  3098. ; "Data" is the data space offset from register DP (the latter not to be confused with Forth variable DP).
  3099. ; The system dictionary resides in absolute address space.
  3100.  
  3101. ; Convert absolute address to reg DP relative offset.
  3102.     sname    <ABSTODATA>    ; abs-addr -- data-addr
  3103.     dd    abstodata    ; Implementation
  3104. abstodata:
  3105.     sub    DWORD PTR [esp],dp
  3106.     next
  3107.  
  3108. ; Convert reg DP relative offset to absolute address.
  3109.     sname    <DATATOABS>    ; data-addr -- abs-addr
  3110.     dd    datatoabs    ; Implementation
  3111. datatoabs:
  3112.     add    DWORD PTR [esp],dp
  3113.     next
  3114.  
  3115. ; Convert absolute address to reg CP relative offset.
  3116.     sname    <ABSTOCODE>    ; abs-addr -- code-addr
  3117.     dd    abstocode    ; Implementation
  3118. abstocode:
  3119.     sub    DWORD PTR [esp],cp
  3120.     next
  3121.  
  3122. ; Convert reg CP relative offset to absolute address.
  3123.     sname    <CODETOABS>    ; code-addr -- abs-addr
  3124.     dd    codetoabs    ; Implementation
  3125. codetoabs:
  3126.     add    DWORD PTR [esp],cp
  3127.     next
  3128.  
  3129. ; Convert reg CP relative code offset to reg DP relative data offset
  3130.     sname    <CODETODATA>    ; code-addr -- data-addr
  3131.     ctok    NEST        ; Implementation
  3132.     ctok    CODETOABS
  3133.     ctok    ABSTODATA
  3134.     ctok    UNNEST
  3135.  
  3136. ; Convert reg DP relative data offset to reg CP relative code offset
  3137.     sname    <DATATOCODE>    ; data-addr -- code-addr
  3138.     ctok    NEST        ; Implementation
  3139.     ctok    DATATOABS
  3140.     ctok    ABSTOCODE
  3141.     ctok    UNNEST
  3142.  
  3143. ; Convert an offset in the user dictionary to a user dict execution token
  3144.     zname    <MAKETOKEN>    ; code-offset -- user-xt
  3145.     ctok    NEST        ; Implementation detail
  3146.     literal    userdictmask
  3147.     ctok    OR
  3148.     ctok    UNNEST
  3149.  
  3150. ; Detect if a given token is from the user dictionary
  3151.     znamemanque    <USERTOKEN?>
  3152. fw_USERTOKENQ:            ; xt -- flag
  3153.     ctok    NEST
  3154.     literal    userdictmask
  3155.     ctok    AND
  3156.     ctok    ZEROEQ
  3157.     ctok    ZEROEQ
  3158.     ctok    UNNEST
  3159.  
  3160. ; Unmask a user dictionary token
  3161.     zname    <DETOKEN>    ; user-xt -- code-offset
  3162.     ctok    NEST
  3163.     literal    userdictmask
  3164.     ctok    INVERT
  3165.     ctok    AND
  3166.     ctok    UNNEST
  3167.  
  3168. ;--( Compiler )
  3169. ; Any compiler word with "xt" in the stack args presumes that a valid form of xt is present on the stack in that position.
  3170.  
  3171.     zname    <SAVEDEPTH>    ; i*x -- i*x
  3172.     ctok    NEST        ; Implementation
  3173.     ctok    SP_FETCH
  3174.     literal    cstack
  3175.     ctok    STORE
  3176.     ctok    UNNEST
  3177.  
  3178.     zname    <CHECKDEPTH>    ; j*x -- j*x [ 0 | n if stack has changed ]
  3179.     ctok    NEST        ; Implementation
  3180.     ctok    SP_FETCH
  3181.     literal    cstack
  3182.     ctok    FETCH
  3183.     ctok    MINUS
  3184.     ctok    UNNEST
  3185.  
  3186.     zname    <HEADER>    ; c-addr u --
  3187.     ctok    NEST        ; Implementation
  3188.     ctok    DP
  3189.     ctok    FETCH        ; -- c-addr u code-offset
  3190.     ctok    MAKETOKEN    ; -- c-addr u valid-link-token
  3191.     literal    last        ; -- c-addr u valid-link-token a-addr
  3192.     ctok    STORE        ; -- c-addr u             keep token for last link added to dictionary
  3193.     ctok    GET_CURRENT    ; -- c-addr u wid
  3194.     ctok    FETCH        ; -- c-addr u a-addr
  3195.     ctok    FETCH        ; -- c-addr u token
  3196.     ctok    COMPCOMMA    ; -- c-addr u             compile back-link to previous definiton in wl
  3197.     ctok    DUP        ; -- c-addr u u
  3198.     literal    16
  3199.     ctok    LSHIFT        ; -- c-addr u u<<16        because we are going to store two words as a dword
  3200.     literal    0FFFFH        ; -- c-addr u u 0ffff
  3201.     ctok    OR        ; -- c-addr u 0ffffuuuu
  3202.     ctok    COMPCOMMA    ; -- c-addr u
  3203.     ctok    DP
  3204.     ctok    FETCH        ; -- c-addr u code-offset
  3205.     ctok    CODETODATA    ; -- c-addr u a-addr
  3206.     ctok    SWAP        ; -- c-addr a-addr u
  3207.     ctok    CHARS        ; -- c-addr a-addr uchars
  3208.     ctok    DUP        ; -- c-addr a-addr ubytes ubytes
  3209.     ctok    TO_R        ; -- c-addr a-addr ubytes        R: -- ubytes
  3210.     ctok    MOVE        ; --                    R: -- ubytes
  3211.     ctok    R_FROM        ; -- ubytes                R: --
  3212.     ctok    DP
  3213.     ctok    FETCH        ; -- ubytes code-offset
  3214.     ctok    PLUS        ; -- n
  3215.     ctok    ALIGNED        ; -- n'
  3216.     ctok    DP        ; -- n a-addr
  3217.     ctok    STORE        ; --
  3218.     ctok    UNNEST
  3219.  
  3220.     zname    <LINKIT>    ; --
  3221.     ctok    NEST        ; Implementation
  3222.     literal    last
  3223.     ctok    FETCH
  3224.     ctok    GET_CURRENT
  3225.     ctok    FETCH
  3226.     ctok    STORE
  3227.     ctok    UNNEST
  3228.  
  3229. ; This one's why ";" doesn't reset the system variable "nonaming"
  3230.     fname    <IMMEDIATE>    ; --
  3231.     ctok    NEST        ; CORE
  3232.     literal    nonaming
  3233.     ctok    FETCH
  3234.     literal    -32        ; zero-length string THROW
  3235.     ctok    AND
  3236.     ctok    THROW        ; a :NONAME word can't be IMMEDIATE
  3237.     literal    last
  3238.     ctok    FETCH
  3239.     ctok    TOKENTODATA
  3240.     ctok    LINKTONAME
  3241.     ctok    DUP
  3242.     ctok    C_FETCH
  3243.     literal    immedMask
  3244.     ctok    OR
  3245.     ctok    SWAP
  3246.     ctok    C_STORE
  3247.     ctok    UNNEST
  3248.  
  3249. ; Can't use our name header macros with this one!
  3250.     linkme    flinkptr
  3251.     countcell    1
  3252.     db    ':',0    
  3253.     align    4        ; "name" --
  3254. fw_COLON:            ; CORE
  3255.     ctok    NEST
  3256.     literal    inDefinition
  3257.     ctok    FETCH
  3258.     compif    colon1
  3259.     literal    -29
  3260.     ctok    THROW        ; nested compilation
  3261. colon1: ctok    TRUE
  3262.     literal    inDefinition    ; we're in a : definition now, prevent nested compilation
  3263.     ctok    STORE
  3264.     ctok    BL
  3265.     ctok    WORD
  3266.     ctok    COUNT
  3267.     ctok    QDUP
  3268.     ctok    ZEROEQ
  3269.     compif    colonnzero
  3270.     literal    -16
  3271.     ctok    THROW
  3272. colonnzero:
  3273.     ctok    FALSE
  3274.     literal    nonaming
  3275.     ctok    STORE        ; this is not a :NONAME defintion
  3276.     ctok    HEADER
  3277.     compelse    noname1    ; continue on in :NONAME
  3278.  
  3279. ; Can't use our name header macros with this one!
  3280.     linkme    flinkptr
  3281.     countcell    7
  3282.     db    ':',0,'N',0,'O',0,'N',0,'A',0,'M',0,'E',0
  3283.     align    4        ; -- | xt (when nonaming)
  3284. fw_noname:            ; CORE EXT
  3285.     ctok    NEST
  3286.     ctok    TRUE
  3287.     literal    inDefinition
  3288.     ctok    FETCH
  3289.     compif    noname0
  3290.     literal    -29
  3291.     ctok    THROW        ; nested compilation
  3292. noname0:
  3293.     literal    inDefinition    ; we're in a : definition now, prevent nested compilation
  3294.     ctok    STORE
  3295.     ctok    TRUE
  3296.     literal    nonaming
  3297.     ctok    STORE        ; this is a :NONAME defintion
  3298.     ctok    DP
  3299.     ctok    FETCH
  3300.     ctok    MAKETOKEN
  3301.     literal last
  3302.     ctok    STORE        ; so semicolon knows what to put on the stack
  3303. noname1:            ; colon ":" jumps here
  3304.     ctok    SAVEDEPTH    ; save stack depth to be checked by ";"
  3305.     ctok    DOLIT
  3306.     ctok    NEST
  3307.     ctok    COMPCOMMA
  3308.     ctok    RBRACKET
  3309.     ctok    UNNEST
  3310.  
  3311.     zname    <STATEABORT>    ; --
  3312.     ctok    NEST        ; Implementation
  3313.     ctok    STATE
  3314.     ctok    FETCH
  3315.     ctok    ZEROEQ        ; state zero? we're interpreting
  3316.     literal    -14        ; Interpreting a compile-only word throw
  3317.     ctok    AND
  3318.     ctok    THROW
  3319.     ctok    UNNEST
  3320.  
  3321. ; Can't use our name header macros with this one!
  3322.     linkme    flinkptr
  3323.     countcell    <immedMask or 1>
  3324.     db    ';',0    
  3325.     align    4        ; -- | xt (when nonaming)
  3326. fw_SEMICOLON:            ; CORE
  3327.     ctok    NEST
  3328.     ctok    STATEABORT
  3329.     ctok    FALSE
  3330.     literal    inDefinition    ; we're now out of a : or :NONAME
  3331.     ctok    STORE
  3332.     ctok    DOLIT
  3333.     ctok    UNNEST
  3334.     ctok    COMPCOMMA
  3335.     ctok    LBRACKET
  3336.     ctok    CHECKDEPTH
  3337.     compif    semi_done
  3338.     literal    -52
  3339.     ctok    THROW
  3340.     ctok    EXIT
  3341. semi_done:
  3342.     literal    nonaming
  3343.     ctok    FETCH
  3344.     compif    semi_named
  3345.     literal    last        ; unnamed, get xt for last definition and leave on stack
  3346.     ctok    FETCH
  3347.     ctok    EXIT
  3348. semi_named:
  3349.     ctok    LINKIT        ; named, link in to compilation wordlist
  3350.     ctok    UNNEST
  3351.  
  3352.     fnamemanque    <]>    ; --
  3353. fw_RBRACKET:            ; CORE
  3354.     ctok    NEST
  3355.     ctok    TRUE
  3356.     ctok    STATE
  3357.     ctok    STORE
  3358.     ctok    UNNEST
  3359.  
  3360.     finamemanque    <[>    ; --
  3361. fw_LBRACKET:            ; CORE
  3362.     ctok    NEST
  3363.     ctok    FALSE
  3364.     ctok    STATE
  3365.     ctok    STORE
  3366.     ctok    UNNEST
  3367.  
  3368.     fname    <STATE>        ; -- a-addr
  3369.     ctok    DOCONST        ; CORE
  3370.     dd    var_state
  3371.  
  3372.     nname    <DP>        ; -- a-addr
  3373.     ctok    DOCONST        ; Not in Standard
  3374.     dd    dictp
  3375.  
  3376. ; Can't use our name header macros with this one!
  3377.     linkme    flinkptr
  3378.     countcell    8
  3379.     db    'C',0,'O',0,'M',0,'P',0,'I',0,'L',0,'E',0,',',0    
  3380.     align    4            ; xt --
  3381. fw_COMPCOMMA:                ; CORE EXT
  3382.     ctok    NEST
  3383.     ctok    DP            ; -- xt dp
  3384.     ctok    DUP            ; -- xt dp dp
  3385.     ctok    FETCH            ; -- xt dp @dp
  3386.     ctok    ALIGNED            ; -- xt dp @dp'
  3387.     ctok    ROT            ; -- dp @dp' xt
  3388.     ctok    OVER            ; -- dp @dp' xt @dp'
  3389.     ctok    CODETODATA        ; -- dp @dp' xt a-addr
  3390.     ctok    STORE            ; -- dp @dp'
  3391.     ctok    CELL_PLUS        ; -- dp @dp''
  3392.     ctok    SWAP            ; -- @dp'' dp(a-addr)
  3393.     ctok    STORE            ; --
  3394.     ctok    UNNEST
  3395.  
  3396.     finame    <RECURSE>    ; --
  3397.     ctok    NEST        ; CORE
  3398.     ctok    STATEABORT
  3399.     literal    last
  3400.     ctok    FETCH
  3401.     ctok    TOKENTODATA
  3402.     ctok    LINKTOEXE
  3403.     ctok    DATATOCODE
  3404.     ctok    MAKETOKEN
  3405.     ctok    COMPCOMMA
  3406.     ctok    UNNEST
  3407.  
  3408. ; Can't use our name header macros with this one!
  3409.     linkme    flinkptr
  3410.     countcell    5
  3411.     db    '>',0,'B',0,'O',0,'D',0,'Y',0
  3412.     align    4            ; xt --
  3413. fw_TO_BODY:                ; CORE
  3414.     ctok    NEST
  3415.     ctok    TOKENTODATA
  3416.     ctok    DUP
  3417.     ctok    FETCH
  3418.     ctok    DUP
  3419.     ctok    DOLIT
  3420.     ctok    DOCONST
  3421.     ctok    EQUAL
  3422.     ctok    SWAP
  3423.     ctok    DOLIT
  3424.     ctok    DODOES
  3425.     ctok    EQUAL
  3426.     ctok    OR
  3427.     ctok    ZEROEQ
  3428.     compif    to_body1
  3429.     literal    -31
  3430.     ctok    THROW
  3431. to_body1:
  3432.     ctok    CELL_PLUS
  3433.     ctok    FETCH
  3434.     ctok    UNNEST
  3435.  
  3436.     fname    <CREATE>    ; "name" --
  3437.     ctok    NEST        ; CORE
  3438.     ctok    ALIGN
  3439.     ctok    BL
  3440.     ctok    WORD
  3441.     ctok    COUNT
  3442.     ctok    QDUP
  3443.     ctok    ZEROEQ
  3444.     compif    create1
  3445.     literal    -16
  3446.     ctok    THROW
  3447. create1:
  3448.     ctok    HEADER
  3449.     ctok    DOLIT
  3450.     ctok    DOCONST
  3451.     ctok    COMPCOMMA
  3452.     ctok    HERE
  3453.     ctok    COMPCOMMA
  3454.     ctok    LINKIT
  3455.     ctok    UNNEST
  3456.  
  3457.     fname    <VARIABLE>    ; "name" --
  3458.     ctok    NEST        ; CORE
  3459.     ctok    CREATE
  3460.     literal    1
  3461.     ctok    CELLS
  3462.     ctok    ALLOT
  3463.     ctok    UNNEST
  3464.  
  3465.     fname    <CONSTANT>    ; x "name" --
  3466.     ctok    NEST        ; CORE
  3467.     ctok    CREATE
  3468.     ctok    DP
  3469.     ctok    FETCH
  3470.     ctok    CODETODATA
  3471.     literal    1
  3472.     ctok    CELLS
  3473.     ctok    MINUS
  3474.     ctok    STORE
  3475.     ctok    UNNEST
  3476.  
  3477.     zname    <MAKEDOES>    ; xt --
  3478.     ctok    NEST        ; Implementation
  3479.     ctok    DOLIT
  3480.     ctok    DODOES
  3481.     literal    last        ; Link token left by the execution of CREATE
  3482.     ctok    FETCH
  3483.     ctok    TOKENTODATA
  3484.     ctok    LINKTOEXE    ; Link token is now data address of execution vector
  3485.     ctok    STORE        ; Now execution vector of CREATEd word is overwritten with DODOES
  3486.     ctok    COMPCOMMA    ; compile the xt for the DOES> body
  3487.     ctok    UNNEST
  3488.  
  3489. ; Can't use our name header macros with this one!
  3490.     linkme    flinkptr
  3491.     countcell    <5 or immedMask>
  3492.     db    'D',0,'O',0,'E',0,'S',0,'>',0
  3493.     align    4            ; --
  3494. fw_DOES:                ; CORE
  3495.     ctok    NEST
  3496.     ctok    DOLIT
  3497.     ctok    DOLIT
  3498.     ctok    COMPCOMMA        ; we are laying down a literal
  3499.     ctok    DP
  3500.     ctok    FETCH
  3501.     literal    3
  3502.     ctok    CELLS
  3503.     ctok    PLUS            ; the literal is the dict pointer plus the cells laid down by DOES> ..
  3504.     ctok    COMPCOMMA        ; .. up to the code laid down in the DOES> body.
  3505.     ctok    DOLIT
  3506.     ctok    MAKETOKEN
  3507.     ctok    COMPCOMMA        ; Then MAKETOKEN has to be executed on that literal at DOES> time
  3508.     ctok    DOLIT
  3509.     ctok    MAKEDOES        ; Resultant xt is consumed by MAKEDOES
  3510.     ctok    COMPCOMMA
  3511.     ctok    DOLIT
  3512.     ctok    EXIT
  3513.     ctok    COMPCOMMA        ; Then we EXIT the CREATE .. DOES> definition but continue to compile
  3514.     ctok    UNNEST
  3515.  
  3516.     finame    <LITERAL>    ; x --
  3517.     ctok    NEST        ; CORE
  3518.     ctok    DOLIT
  3519.     ctok    DOLIT
  3520.     ctok    COMPCOMMA
  3521.     ctok    COMPCOMMA
  3522.     ctok    UNNEST
  3523.  
  3524.     finamemanque    <2LITERAL>    ; x x --
  3525. fw_TWO_LITERAL:            ; DOUBLE
  3526.     ctok    NEST
  3527.     ctok    DOLIT
  3528.     ctok    DODLIT
  3529.     ctok    COMPCOMMA
  3530.     ctok    COMPCOMMA
  3531.     ctok    COMPCOMMA
  3532.     ctok    UNNEST
  3533.  
  3534.     finame    <POSTPONE>    ; "name" --
  3535.     ctok    NEST        ; CORE
  3536.     ctok    STATEABORT
  3537.     ctok    BL
  3538.     ctok    WORD
  3539.     ctok    FIND
  3540.     ctok    DUP
  3541.     ctok    ZEROEQ
  3542.     compif    postpone1
  3543.     ctok    UNFOUND
  3544. postpone1:
  3545.     ctok    DOLIT        ; first of all, compile this code here ..
  3546.     ctok    STATEABORT    ; ... since ..
  3547.     ctok    COMPCOMMA    ; ... the POSTPONEd construct should THROW -14 if encountered interpretively.
  3548.     ctok    ZEROLT        ; -1 is non-IMMEDIATE
  3549.     compif    postpone2
  3550.     ctok    LITERAL
  3551.     ctok    DOLIT
  3552.     ctok    COMPCOMMA
  3553.     ctok    COMPCOMMA
  3554.     ctok    EXIT
  3555. postpone2:            ; 1 is IMMEDIATE
  3556.     ctok    COMPCOMMA
  3557.     ctok    UNNEST
  3558.  
  3559. ;--( Branches )
  3560.  
  3561.     zname    <UNRESOLVED>    ; --
  3562.     ctok    NEST        ; Implementation
  3563.     literal    -22
  3564.     ctok    THROW
  3565.  
  3566.     finame    <IF>            ; -- orig
  3567.     ctok    NEST            ; CORE
  3568.     ctok    STATEABORT
  3569.     ctok    DOLIT
  3570.     ctok    DOIF            ; -- xt
  3571.     ctok    COMPCOMMA        ; --
  3572.     ctok    DP
  3573.     ctok    FETCH            ; -- orig
  3574.     ctok    DOLIT
  3575.     ctok    UNRESOLVED        ; -- orig xt
  3576.     ctok    COMPCOMMA        ; -- orig
  3577.     ctok    UNNEST
  3578.  
  3579.     finame    <ELSE>            ; orig1 -- orig2
  3580.     ctok    NEST            ; CORE
  3581.     ctok    STATEABORT
  3582.     ctok    DOLIT
  3583.     ctok    DOELSE            ; -- o1 xt
  3584.     ctok    COMPCOMMA        ; -- o1
  3585.     ctok    DP
  3586.     ctok    FETCH            ; -- o1 o2
  3587.     ctok    SWAP            ; -- o2 o1
  3588.     ctok    DOLIT
  3589.     ctok    UNRESOLVED        ; -- o2 o1 xt    
  3590.     ctok    COMPCOMMA        ; -- o2 o1
  3591.     ctok    DP
  3592.     ctok    FETCH            ; -- o2 o1 resolution
  3593.     ctok    MAKETOKEN        ; -- o2 o1 xt
  3594.     ctok    SWAP            ; -- o2 xt o1
  3595.     ctok    CODETODATA        ; -- o2 xt a-addr
  3596.     ctok    STORE            ; -- o2
  3597.     ctok    UNNEST
  3598.  
  3599.     finame    <THEN>            ; orig --
  3600.     ctok    NEST            ; CORE
  3601.     ctok    STATEABORT
  3602.     ctok    DP
  3603.     ctok    FETCH            ; -- orig resolution
  3604.     ctok    MAKETOKEN        ; -- orig xt
  3605.     ctok    SWAP            ; -- xt orig
  3606.     ctok    CODETODATA        ; -- xt a-addr
  3607.     ctok    STORE            ; --
  3608.     ctok    UNNEST
  3609.  
  3610.     finame    <BEGIN>            ; -- dest
  3611.     ctok    NEST            ; CORE
  3612.     ctok    STATEABORT
  3613.     ctok    DP
  3614.     ctok    FETCH            ; -- dest
  3615.     ctok    UNNEST
  3616.  
  3617.     finame    <UNTIL>            ; dest --
  3618.     ctok    NEST            ; CORE
  3619.     ctok    STATEABORT        
  3620.     ctok    DOLIT
  3621.     ctok    DOUNTIL            ; -- dest xt
  3622.     ctok    COMPCOMMA        ; -- dest
  3623.     ctok    MAKETOKEN        ; -- xt
  3624.     ctok    COMPCOMMA        ; --
  3625.     ctok    UNNEST
  3626.  
  3627.     finame    <WHILE>            ; dest -- orig dest
  3628.     ctok    NEST            ; CORE
  3629.     ctok    STATEABORT        
  3630.     ctok    DOLIT
  3631.     ctok    DOIF            ; -- dest xt
  3632.     ctok    COMPCOMMA        ; -- dest
  3633.     ctok    DP
  3634.     ctok    FETCH            ; -- dest orig
  3635.     ctok    SWAP            ; -- orig dest
  3636.     ctok    DOLIT
  3637.     ctok    UNRESOLVED        ; -- orig dest xt
  3638.     ctok    COMPCOMMA        ; -- orig dest
  3639.     ctok    UNNEST
  3640.     
  3641.     finame    <REPEAT>        ; orig dest --
  3642.     ctok    NEST            ; CORE
  3643.     ctok    STATEABORT
  3644.     ctok    DOLIT
  3645.     ctok    DOELSE            ; -- o d xt
  3646.     ctok    COMPCOMMA        ; -- o d
  3647.     ctok    MAKETOKEN        ; -- o xt
  3648.     ctok    COMPCOMMA        ; -- o
  3649.     ctok    DP
  3650.     ctok    FETCH            ; -- o resolution
  3651.     ctok    MAKETOKEN        ; -- o xt
  3652.     ctok    SWAP            ; -- xt orig
  3653.     ctok    CODETODATA        ; -- xt a-addr
  3654.     ctok    STORE            ; --
  3655.     ctok    UNNEST
  3656.  
  3657.     finame    <AGAIN>            ; dest --
  3658.     ctok    NEST            ; CORE EXT
  3659.     ctok    STATEABORT
  3660.     ctok    DOLIT
  3661.     ctok    DOELSE            ; -- d xt
  3662.     ctok    COMPCOMMA        ; -- d
  3663.     ctok    MAKETOKEN        ; -- xt
  3664.     ctok    COMPCOMMA        ; --
  3665.     ctok    UNNEST
  3666.  
  3667.     finame    <DO>            ; -- do-dest
  3668.     ctok    NEST            ; CORE
  3669.     ctok    STATEABORT
  3670.     ctok    DOLIT
  3671.     ctok    DODO            ; -- xt
  3672.     ctok    COMPCOMMA        ; --
  3673.     ctok    DP
  3674.     ctok    FETCH            ; -- do-dest
  3675.     ctok    DOLIT
  3676.     ctok    UNRESOLVED        ; -- do-dest xt
  3677.     ctok    COMPCOMMA        ; -- do-dest
  3678.     ctok    UNNEST
  3679.  
  3680.     finamemanque    <?DO>        ; -- dest
  3681. fw_QDO:    ctok    NEST            ; CORE
  3682.     ctok    STATEABORT
  3683.     ctok    DOLIT
  3684.     ctok    DOQDO            ; -- xt
  3685.     ctok    COMPCOMMA        ; --
  3686.     ctok    DP
  3687.     ctok    FETCH            ; -- do-dest
  3688.     ctok    DOLIT
  3689.     ctok    UNRESOLVED        ; -- do-dest xt
  3690.     ctok    COMPCOMMA        ; -- do-dest
  3691.     ctok    UNNEST
  3692.  
  3693.     finame    <LOOP>            ; dest --
  3694.     ctok    NEST            ; CORE
  3695.     ctok    STATEABORT
  3696.     ctok    DOLIT
  3697.     ctok    DOLOOP            ; -- dest xt
  3698.     ctok    COMPCOMMA        ; -- dest
  3699.     ctok    DUP            ; -- dest dest
  3700.     ctok    CELL_PLUS        ; -- dest dest'        so that it points beyond UNRESOLVED
  3701.     ctok    MAKETOKEN        ; -- dest xt
  3702.     ctok    COMPCOMMA        ; -- dest
  3703.     ctok    DP
  3704.     ctok    FETCH            ; -- dest resolution
  3705.     ctok    MAKETOKEN        ; -- dest xt
  3706.     ctok    SWAP            ; -- xt dest
  3707.     ctok    CODETODATA        ; -- xt a-addr
  3708.     ctok    STORE            ; --
  3709.     ctok    UNNEST
  3710.  
  3711.     finamemanque    <+LOOP>        ; --
  3712. fw_PLUSLOOP:
  3713.     ctok    NEST            ; CORE
  3714.     ctok    STATEABORT
  3715.     ctok    DOLIT
  3716.     ctok    DOPLUSLOOP        ; -- dest xt
  3717.     ctok    COMPCOMMA        ; -- dest
  3718.     ctok    DUP            ; -- dest dest
  3719.     ctok    CELL_PLUS        ; -- dest dest'        so that it points beyond UNRESOLVED
  3720.     ctok    MAKETOKEN        ; -- dest xt
  3721.     ctok    COMPCOMMA        ; -- dest
  3722.     ctok    DP
  3723.     ctok    FETCH            ; -- dest resolution
  3724.     ctok    MAKETOKEN        ; -- dest xt
  3725.     ctok    SWAP            ; -- xt dest
  3726.     ctok    CODETODATA        ; -- xt a-addr
  3727.     ctok    STORE            ; --
  3728.     ctok    UNNEST
  3729.  
  3730.     fname    <I>            ; -- n|u
  3731.     docode                ; CORE
  3732.     mov    eax,[rp]        ; Calculate current loop index
  3733.     add    eax,cell[rp]
  3734.     push    eax
  3735.     next
  3736.  
  3737.     fname    <J>            ; -- n|u
  3738.     docode                ; CORE
  3739.     mov    eax,3*cell[rp]        ; Calculate next outermost loop index
  3740.     add    eax,4*cell[rp]
  3741.     push    eax
  3742.     next
  3743.  
  3744.     fname    <LEAVE>
  3745.     docode                ; --    R: loop-sys --
  3746.     poprp                ; CORE
  3747.     poprp
  3748.     poprpto    ip
  3749.     next
  3750.  
  3751.     fname    <UNLOOP>        ; --    R: loop-sys --
  3752.     docode                ; CORE
  3753.     poprp
  3754.     poprp
  3755.     poprp
  3756.     next
  3757.  
  3758. ;--( Exception Handling )
  3759.  
  3760.     fname    <ABORT>        ; --
  3761.     ctok    NEST        ; CORE
  3762.     ctok    TRUE
  3763.     ctok    THROW        ; no unnest needed!
  3764.  
  3765. ; Can't use our name header macros with this one!
  3766.     linkme    flinkptr
  3767.     countcell    <6 or immedMask>
  3768.     db    'A',0,'B',0,'O',0,'R',0,'T',0,'"',0    ; ccc<"> --
  3769.     align    4                    ; CORE
  3770. fw_ABORT_QUOTE:
  3771.     ctok    NEST
  3772.     ctok    STATEABORT
  3773.     ctok    DOLIT
  3774.     ctok    DOIF            ; -- xt
  3775.     ctok    COMPCOMMA        ; --
  3776.     ctok    DP
  3777.     ctok    FETCH            ; -- orig
  3778.     ctok    DOLIT
  3779.     ctok    UNRESOLVED        ; -- orig xt
  3780.     ctok    COMPCOMMA        ; -- orig
  3781.     literal    -2
  3782.     ctok    LITERAL
  3783.     ctok    DP
  3784.     ctok    FETCH
  3785.     ctok    S_QUOTE
  3786.     ctok    CODETODATA
  3787.     ctok    DOLIT
  3788.     ctok    THROW
  3789.     ctok    SWAP
  3790.     ctok    STORE            ; overwrite the S" execution engine
  3791.     ctok    DP
  3792.     ctok    FETCH            ; -- orig resolution
  3793.     ctok    MAKETOKEN        ; -- orig xt
  3794.     ctok    SWAP            ; -- xt orig
  3795.     ctok    CODETODATA        ; -- xt a-addr
  3796.     ctok    STORE            ; --
  3797.     ctok    UNNEST
  3798.  
  3799.     fname    <CATCH>            ; i*x xt -- j*x 0 | i*x n)
  3800.     dd    catch            ; EXCEPTION
  3801. catch:    pop    wp            ; execution token
  3802.     fetch    edx,lastCatch        ; save previous catch pointer
  3803.     pushrp    edx            ; (1)
  3804.     pushrp    esp            ; (2) save stack pointer
  3805.     fetch    edx,var_tib        ; save buffer address
  3806.     pushrp    edx            ; (3)
  3807.     fetch    edx,var_numtib        ; save number of chars in input buffer
  3808.     pushrp    edx            ; (4)
  3809.     fetch    edx,var_to_in        ; save index into input buffer
  3810.     pushrp    edx            ; (5)
  3811.     fetch    edx,var_srcid        ; save source id
  3812.     pushrp    edx            ; (6)
  3813.     fetch    edx,var_blk        ; save BLK
  3814.     pushrp    edx            ; (7)
  3815.     pushrp    ip            ; (8) save interpretive pointer
  3816.     store    lastCatch,rp        ; put pointer to this frame in lastCatch variable
  3817.     mov    ecx,OFFSET FLAT:uncatch    ; routine to recover
  3818.     mov    ip,ecx
  3819.     innext                ; eax (the wp) already has the token to execute
  3820.     align    cell
  3821. uncatch:                ; we only end up here if no THROW intervenes
  3822.     docode                ; as if it was a cell in a colon definition pointing to ...
  3823.     docode                ; ... a definition which started here ...
  3824.     fetch    rp,lastCatch        ; restore return pointer from lastCatch, points to frame
  3825.     poprpto    ip            ; (8) restore IP that was stashed by CATCH
  3826.     poprp                ; (7) discard BLK
  3827.     poprp                ; (6) discard SOURCE-ID
  3828.     poprp                ; (5) discard >IN
  3829.     poprp                ; (4) discard #TIB
  3830.     poprp                ; (3) discard 'TIB
  3831.     poprp                ; (2) discard DSP
  3832.     poprpto    eax            ; (1) lastCatch
  3833.     store    lastCatch,eax
  3834.     xor    eax,eax
  3835.     push    eax            ; 0 return says all is well
  3836.     next
  3837.  
  3838.     fname    <THROW>            ; k*x n -- k*x | i*x n
  3839.     docode                ; EXCEPTION
  3840.     pop    edx            ; check arg
  3841.     and    edx,edx
  3842.     jne    throw1            ; zero? continue harmlessly
  3843.     next
  3844. throw1:                    ; arg was non-zero
  3845.     fetch    rp,lastCatch        ; set return stack back to where it was
  3846.     store    lastCaught,ip        ; save IP pointing to cell following the THROW
  3847.     poprpto    ip            ; (8) restore IP that was stashed by CATCH
  3848.     poprpto    eax            ; (7)
  3849.     store    var_blk,eax        ; restore BLK
  3850.     poprpto    eax            ; (6)
  3851.     store    var_srcid,eax        ; restore SOURCE-ID
  3852.     poprpto    eax            ; (5))
  3853.     store    var_to_in,eax        ; restore >IN
  3854.     poprpto    eax            ; (4)
  3855.     store    var_numtib,eax        ; restore #TIB
  3856.     poprpto    eax            ; (3)
  3857.     store    var_tib,eax        ; restore 'TIB
  3858.     poprpto    esp            ; (2) restore DSP
  3859.     poprpto    eax            ; (1)
  3860.     store    lastCatch,eax        ; restore lastCatch
  3861.     push    edx            ; the throw code
  3862.     next
  3863.  
  3864.     zname    <FIRSTCATCH>        ; --    R: -- catch-sys
  3865.     docode                ; Implementation
  3866.     xor    edx,edx
  3867.     pushrp    edx            ; there is no previous catch to push in this case
  3868.     pushrp    esp            ; save stack pointer
  3869.     fetch    edx,var_tib        ; save buffer address
  3870.     pushrp    edx
  3871.     fetch    edx,var_numtib        ; save number of chars in input buffer
  3872.     pushrp    edx
  3873.     fetch    edx,var_to_in        ; save number of chars in input buffer
  3874.     pushrp    edx
  3875.     fetch    edx,var_srcid        ; save source id
  3876.     pushrp    edx
  3877.     fetch    edx,var_blk        ; save BLK
  3878.     pushrp    edx
  3879.     mov    eax,OFFSET FLAT:fw_CATCHFIRSTCATCH+cell
  3880.     pushrp    eax            ; the CATCH of last resort!
  3881.     store    lastCatch,rp        ; put pointer to this frame in lastCatch variable
  3882.     next                ; onwards!
  3883.  
  3884.     zname    <CATCHFIRSTCATCH>    ; --
  3885.     ctok    NEST            ; Implementation
  3886.     ctok    DUP
  3887.     literal    -2            ; The ABORT" throw
  3888.     ctok    EQUAL
  3889.     compif    catchfirst1
  3890.     literal    lastCaught        ; Get IP which is pointing to pointer to string
  3891.     ctok    FETCH            ; IP
  3892.     ctok    TOKENTODATA    
  3893.     ctok    FETCH            ; data address of counted string    
  3894.     ctok    COUNT
  3895.     ctok    TYPE
  3896.     compelse    catchabort    ; fall thru into the tail of ABORT throw
  3897. catchfirst1:
  3898.     ctok    DUP
  3899.     literal    -1            ; The ABORT throw
  3900.     ctok    EQUAL
  3901.     compif    catchfirst4
  3902. catchabort:
  3903.     ctok    SP0
  3904.     ctok    FETCH
  3905.     ctok    SP_STORE
  3906.     ctok    FIRSTCATCH        ; if we hit the LASTCATCH frame, SP=SP0, RP=RP0, etc, just rebuild LASTCATCH
  3907.     ctok    QUIT            ; just QUIT
  3908. catchfirst4:
  3909.     ctok    DUP
  3910.     literal    -4
  3911.     ctok    EQUAL
  3912.     compif    catchfirst13
  3913.     ctok    DOKDOTQUOTE        ; stack underflow abort
  3914.     dd    stackUnderMsg
  3915.     compelse    catchabort    ; exit via an ABORT
  3916. catchfirst13:
  3917.     ctok    DUP
  3918.     literal    -13
  3919.     ctok    EQUAL
  3920.     compif    catchfirst14
  3921.     ctok    DOKDOTQUOTE        ; undefined word abort
  3922.     dd    undefinedMsg
  3923.     compelse    catchabort    ; exit via an ABORT
  3924. catchfirst14:
  3925.     ctok    DUP
  3926.     literal    -14
  3927.     ctok    EQUAL
  3928.     compif    catchfirst16
  3929.     ctok    DOKDOTQUOTE        ; compile-only abort
  3930.     dd    compOnlyMsg
  3931.     compelse    catchabort    ; exit via an ABORT
  3932. catchfirst16:
  3933.     ctok    DUP
  3934.     literal    -16
  3935.     ctok    EQUAL
  3936.     compif    catchfirst22
  3937.     ctok    DOKDOTQUOTE        ; zero-length name string abort
  3938.     dd    zeroStringMsg
  3939.     compelse    catchabort    ; exit via an ABORT
  3940. catchfirst22:
  3941.     ctok    DUP
  3942.     literal    -22
  3943.     ctok    EQUAL
  3944.     compif    catchfirst29
  3945.     ctok    DOKDOTQUOTE        ; control structure abort
  3946.     dd    conStructMsg
  3947.     compelse    catchabort    ; exit via an ABORT
  3948. catchfirst29:
  3949.     ctok    DUP
  3950.     literal    -29
  3951.     ctok    EQUAL
  3952.     compif    catchfirst31
  3953.     ctok    FALSE
  3954.     literal    inDefinition        ; reset internal var indicating : or :NONAME in progress
  3955.     ctok    STORE
  3956.     ctok    DOKDOTQUOTE        ; >BODY on non-CREATE word
  3957.     dd    compNestMsg
  3958.     compelse    catchabort    ; exit via an ABORT
  3959. catchfirst31:
  3960.     ctok    DUP
  3961.     literal    -31
  3962.     ctok    EQUAL
  3963.     compif    catchfirst33
  3964.     ctok    DOKDOTQUOTE        ; >BODY on non-CREATE word
  3965.     dd    toBodyMsg
  3966.     compelse    catchabort    ; exit via an ABORT
  3967. catchfirst33:
  3968.     ctok    DUP
  3969.     literal    -33
  3970.     ctok    EQUAL
  3971.     compif    catchfirst34
  3972.     ctok    DOKDOTQUOTE        ; BLOCK read error
  3973.     dd    blockReadMsg
  3974.     compelse    catchabort    ; exit via an ABORT
  3975. catchfirst34:
  3976.     ctok    DUP
  3977.     literal    -34
  3978.     ctok    EQUAL
  3979.     compif    catchfirst35
  3980.     ctok    DOKDOTQUOTE        ; BLOCK write error
  3981.     dd    blockWriteMsg
  3982.     compelse    catchabort    ; exit via an ABORT
  3983. catchfirst35:
  3984.     ctok    DUP
  3985.     literal    -35
  3986.     ctok    EQUAL
  3987.     compif    catchfirst37
  3988.     ctok    DOKDOTQUOTE        ; BLOCK number error
  3989.     dd    blockNumMsg
  3990.     compelse    catchabort    ; exit via an ABORT
  3991. catchfirst37:
  3992.     ctok    DUP
  3993.     literal    -37
  3994.     ctok    EQUAL
  3995.     compif    catchfirst49
  3996.     ctok    LastError
  3997.     ctok    FETCH            ; Error should be in LastError if we reach this point
  3998.     ctok    DOKDOTQUOTE        ; File I/O exception
  3999.     dd    fileIOMsg        ; this message needs a trailing space!
  4000.     ctok    U_DOT            ; Display
  4001.     compelse    catchabort    ; exit via an ABORT
  4002. catchfirst49:
  4003.     ctok    DUP
  4004.     literal    -49            ; search order overflow THROW
  4005.     ctok    EQUAL
  4006.     compif    catchfirst50
  4007.     ctok    DOKDOTQUOTE
  4008.     dd    srchOverMsg
  4009.     compelse    catchabort    ; exit via an ABORT
  4010. catchfirst50:
  4011.     ctok    DUP
  4012.     literal    -50            ; search order underflow THROW
  4013.     ctok    EQUAL
  4014.     compif    catchfirst52
  4015.     ctok    DOKDOTQUOTE
  4016.     dd    srchUnderMsg
  4017.     compelse    catchabort    ; exit via an ABORT
  4018. catchfirst52:
  4019.     ctok    DUP
  4020.     literal    -52
  4021.     ctok    EQUAL
  4022.     compif    catchfirst56
  4023.     ctok    DOKDOTQUOTE
  4024.     dd    cStackMsg        ; control flow stack changed
  4025.     compelse    catchabort    ; exit via ABORT
  4026. catchfirst56:
  4027.     ctok    DUP
  4028.     literal    -56
  4029.     ctok    EQUAL
  4030.     compif    catchall
  4031.     ctok    DROP            ; drop the -56
  4032.     ctok    FIRSTCATCH        ; if we hit the LASTCATCH frame, SP=SP0, RP=RP0, etc, just rebuild LASTCATCH
  4033.     ctok    QUIT            ; just QUIT
  4034. catchall:                ; the catch-all case for THROWs outside those we have handled
  4035.     literal    throwMsg
  4036.     ctok    ABSTODATA
  4037.     literal    throwMsgLen
  4038.     ctok    TYPE
  4039.     ctok    DOT
  4040.     charlit    '@'
  4041.     ctok    EMIT
  4042.     ctok    SPACE
  4043.     literal    lastCaught
  4044.     ctok    FETCH
  4045.     literal    cell
  4046.     ctok    MINUS
  4047.     ctok    DOT
  4048.     ctok    FIRSTCATCH        ; if we hit the LASTCATCH frame, SP=SP0, RP=RP0, etc, just rebuild LASTCATCH
  4049.     ctok    QUIT
  4050.     ctok    UNNEST
  4051.  
  4052. ;--( Tools & Utilities )
  4053.  
  4054.     nname    <NOOP>        ; --
  4055.     docode            ; Doesn't appear in Standard
  4056.     nop
  4057.     next
  4058.  
  4059.     zname    <DUMPLINE>    ; a-addr1 -- a-addr2
  4060.     ctok    NEST
  4061.     ctok    DUP
  4062.     ctok    DUP        ; -- a-addr1 a-addr1
  4063.     ctok    FALSE
  4064.     ctok    LSHARP        ; -- a-addr1 ud
  4065.     literal    8
  4066.     ctok    FALSE
  4067.     compdo    dumpline2
  4068. dumpline1:
  4069.     ctok    SHARP        ; -- a-addr1 ud'
  4070.     comploop    dumpline1
  4071. dumpline2:
  4072.     ctok    SHARPR
  4073.     ctok    TYPE        ; -- a-addr1            print line address
  4074.     ctok    SPACE
  4075.     literal    8
  4076.     literal    0
  4077.     compdo    dumpline4
  4078. dumpline3:            ; -- addr addr
  4079.     ctok    COUNT        ; -- addr addr' char
  4080.     ctok    FALSE
  4081.     ctok    LSHARP
  4082.     ctok    SHARP
  4083.     ctok    SHARP
  4084.     ctok    SHARP
  4085.     ctok    SHARP
  4086.     ctok    SHARPR
  4087.     ctok    TYPE        ; -- addr addr'            print two bytes as a word
  4088.     ctok    SPACE
  4089.     comploop    dumpline3
  4090. dumpline4:
  4091.     ctok    DROP        ; -- addr
  4092.     literal    8
  4093.     literal    0
  4094.     compdo    dumpline6
  4095. dumpline5:
  4096.     ctok    COUNT
  4097.     literal    0FFh
  4098.     ctok    AND
  4099.     ctok    DUP
  4100.     literal    01fH        ; -- addr' char char 01fh
  4101.     ctok    GREATER
  4102.     compif    dumplinenochar
  4103.     ctok    EMIT
  4104.     compelse    dumplinez
  4105. dumplinenochar:
  4106.     ctok    DROP
  4107.     charlit    '.'
  4108.     ctok    EMIT
  4109. dumplinez:
  4110.     comploop    dumpline5
  4111. dumpline6:
  4112.     ctok    UNNEST        ; -- addr'
  4113.  
  4114.     fname    <DUMP>        ; addr u --
  4115.     ctok    NEST        ; TOOLKIT
  4116.     ctok    BASE        ; -- addr u a-addr
  4117.     ctok    FETCH        ; -- addr u n
  4118.     ctok    TO_R        ; -- addr u                    R: -- base
  4119.     ctok    HEX
  4120.     ctok    CR
  4121.     literal    dumpHdr        ; print a header here
  4122.     ctok    ABSTODATA
  4123.     ctok    COUNT
  4124.     ctok    TYPE        ; -- addr u                    R: -- base
  4125.     ctok    CR
  4126.     ctok    SWAP        ; -- u addr
  4127.     ctok    FALSE        ; -- u addr 0
  4128.     literal    16        ; Now align the dump region
  4129.     ctok    UMSLMOD        ; -- u1 u2r addr/8
  4130.     ctok    SWAP        ; -- u addr/8 u2r
  4131.     ctok    TO_R        ; -- u addr/8                R: -- u2r
  4132.     literal    16
  4133.     ctok    UMSTAR        ; -- u addr' 0                R: -- u2r
  4134.     ctok    DROP        ; -- u addr'                R: -- u2r
  4135.     ctok    SWAP        ; -- addr u                R: -- u2r
  4136.     ctok    FALSE        ; -- addr u 0                R: -- u2r
  4137.     literal    16
  4138.     ctok    UMSLMOD        ; -- addr u1r u2q                R: -- u2r
  4139.     ctok    SWAP        ; -- addr u2q u1r                R: -- u2r
  4140.     ctok    ZERONE        ; -- addr u/16 [-1 | 0]                R: -- u2r
  4141.     ctok    NEGATE        ; -- addr u/16 [1 | 0]                R: -- u2r
  4142.     ctok    PLUS        ; -- addr u(number of iterations)        R: -- u2r
  4143.     ctok    R_FROM        ; -- addr u/16 u2r                R: --
  4144.     ctok    ZERONE        ; -- addr u/16  [1|0] [-1 | 0]
  4145.     ctok    NEGATE        ; -- addr u/16  [1|0] [1 | 0]
  4146.     ctok    PLUS        ; -- addr u(number of iterations)    ; add line if bytes modded
  4147.     ctok    FALSE        ; -- addr u/16 0
  4148.     compdo    dump2        ; dump that many lines
  4149. dump1:    ctok    DUMPLINE
  4150.     ctok    CR
  4151. ;    ctok    KEY_Q
  4152. ;    compif    dumpcontinue
  4153. ;    ctok    LEAVE
  4154. dumpcontinue:
  4155.     comploop    dump1
  4156. dump2:
  4157.     ctok    DROP
  4158.     ctok    R_FROM
  4159.     ctok    BASE
  4160.     ctok    STORE        : --                        R: --
  4161.     ctok    UNNEST
  4162.  
  4163.     fname    <BYE>        ; --
  4164.     dd    byebye        ; TOOLKIT EXT
  4165. byebye:                ; exit program
  4166.     fetch    ebp,ntConEBP
  4167.     fetch    esp,ntConESP
  4168.     fetch    eax,memHandle
  4169.     push    eax
  4170.     stdCall    _LocalUnlock,eax
  4171.     pop    eax
  4172.     stdCall    _LocalFree,eax
  4173.     pop    edi
  4174.     pop    esi
  4175.     pop    ebx
  4176.     leave
  4177.     stdCall    _ExitProcess,0
  4178.  
  4179.     fnamemanque    <AT-XY>            ; u1 u2 --
  4180. fw_AT_XY:                    ; FACILITY
  4181.     docode
  4182.     pop    eax                ; y
  4183.     pop    edx                ; x
  4184.     shl    eax,16
  4185.     mov    ax,dx                ; compose COORD wherein Y is higher in mem than X
  4186.     stdCall    _SetConsoleCursorPosition,<DWORD PTR stdOut[dp],eax>
  4187.     and    eax,eax                ; success is "C" TRUE
  4188. ;    je    at_xy1                ; if failure, we'll do some more work
  4189.     mov    DWORD PTR lastError[dp],-1    ; success, set lastErr
  4190.     next                    ; success, exit
  4191. at_xy1:    jmp    doLastErr            ; return to NEXT via doLastErr
  4192.     
  4193.     fname    <PAGE>                ; --
  4194.     docode                    ; FACILITY
  4195.     mov    eax,20H                ; character to fill with
  4196.     mov    edx,32767            ; !!!***!!! HACK HACK HACK we have to calculate this correctly
  4197.     xor    ecx,ecx                ; Coord for fill, i.e., "0@0"
  4198.     stdCall    _FillConsoleOutputCharacterW,<DWORD PTR stdOut[dp],eax,edx,ecx,OFFSET FLAT:numWritten>
  4199.     and    eax,eax                ; success is "C" TRUE
  4200. ;    je    at_xy1                ; failure, exit re-using code above in AT-XY
  4201.     xor    eax,eax                ; make a "0@0" Coord for next call
  4202.     stdCall    _SetConsoleCursorPosition,<DWORD PTR stdOut[dp],eax>
  4203.     and    eax,eax                ; success is "C" TRUE
  4204. ;    je    at_xy1                ; failure, exit re-using code above in AT-XY
  4205.     mov    DWORD PTR lastError[dp],-1    ; success, set lastErr
  4206.     next
  4207.  
  4208.     fnamemanque    <ENVIRONMENT?>    ; c-addr u -- false | i*x true
  4209. fw_ENVQ:                ; CORE
  4210.     ctok    NEST
  4211.     ctok    TWO_DROP
  4212.     ctok    FALSE            ; don't know nuttin'
  4213.     ctok    UNNEST
  4214.  
  4215. ;--( File Words )
  4216.  
  4217.     include    jx4files.a        ; jax4th.asm is just getting too big!
  4218.  
  4219. ;--( Platform-Specific Stuff )
  4220.  
  4221. ; Copy unicode string to asciiz string in special sys buffer, null terminates
  4222.     sname    <ASCIIZ>        ; c-addr u -- addr
  4223.     ctok    NEST            ; Not in Standard, used for syscalls that don't take unicode
  4224.     ctok    TUCK            ; -- u c-addr u
  4225.     ctok    FALSE            ; -- u c-addr u 0
  4226.     compqdo    asciiz2
  4227. asciiz1:
  4228.     ctok    DUP            ; -- u c-addr c-addr
  4229.     ctok    C_FETCH            ; -- u c-addr char
  4230.     literal    asciizBuffer        ; -- u c-addr char addr
  4231.     ctok    I
  4232.     ctok     PLUS            ; -- u c-addr char addr'
  4233.     ctok    B_STORE            ; -- u c-addr
  4234.     ctok    CHAR_PLUS        ; -- u c-addr'
  4235.     comploop    asciiz1
  4236. asciiz2:
  4237.     ctok    DROP            ; -- u
  4238.     literal    asciizBuffer        ; -- u addr
  4239.     ctok    PLUS            ; -- addr'    one past end of byte string
  4240.     ctok    FALSE
  4241.     ctok    SWAP            ; -- 0 addr'
  4242.     ctok    B_STORE            ; --
  4243.     literal    asciizBuffer        ; -- addr    buffer holding ascii byte string
  4244.     ctok    UNNEST
  4245.  
  4246. ; Copy ascii string to unicode string in special sys buffer, null terminates
  4247.     sname    <UNICODE>        ; b-addr u -- addr
  4248.     ctok    NEST            ; Not in Standard, used for syscalls that don't take unicode
  4249.     ctok    TUCK            ; -- u b-addr u
  4250.     ctok    FALSE            ; -- u b-addr u 0
  4251.     compqdo    unicode2
  4252. unicode1:
  4253.     ctok    DUP            ; -- u b-addr b-addr
  4254.     ctok    B_FETCH            ; -- u b-addr char
  4255.     literal    asciizBuffer        ; -- u b-addr char c-addr
  4256.     ctok    I
  4257.     ctok    CHARS
  4258.     ctok     PLUS            ; -- u c-addr char addr'
  4259.     ctok    C_STORE            ; -- u c-addr
  4260.     ctok    ONE_PLUS        ; -- u c-addr'
  4261.     comploop    unicode1
  4262. unicode2:
  4263.     ctok    DROP            ; -- u
  4264.     literal    asciizBuffer        ; -- u addr
  4265.     ctok    CHARS
  4266.     ctok    PLUS            ; -- addr'    one past end of byte string
  4267.     ctok    FALSE
  4268.     ctok    SWAP            ; -- 0 addr'
  4269.     ctok    C_STORE            ; --
  4270.     literal    asciizBuffer        ; -- addr    buffer holding ascii byte string
  4271.     ctok    UNNEST
  4272.  
  4273.     sname    <SYSCALL>            ; abs-addr -- edx eax
  4274.     docode                    ; Call addr and return eax and edx
  4275.     pop    eax
  4276.     call    eax
  4277.     push    edx
  4278.     push    eax
  4279.     next
  4280.  
  4281.     sname    <GetProcAddress>        ; [lpszProc | ordinal] hModule -- abs-addr | nil
  4282.     docode                    ; find a DLL function address from a null-terminated name string
  4283.     call    _GetProcAddress@8            ; parameter if ordinal must have zero (0000h) in hi word
  4284.     push    eax
  4285.     next
  4286.  
  4287.     sname    <LoadLibraryEx>            ; dwFlags 0 lpszLibFile -- hModule | 0
  4288.     docode
  4289.     call    _LoadLibraryExW@12
  4290.     push    eax
  4291.     test    eax,0
  4292.     je    doLastErr            ; if error, set LastError var
  4293.     next
  4294.  
  4295.     sname    <FreeLibrary>            ; hLibModule --
  4296.     docode
  4297.     call    _FreeLibrary@4
  4298.     push    eax
  4299.     test    eax,0
  4300.     je    doLastErr            ; if error, set LastError var
  4301.     next
  4302.  
  4303.     sname    <ENABLE_LINE_INPUT>        ; -- x
  4304.     ctok    DOCONST                ; Con Mode constant value
  4305.     dd    ENABLE_LINE_INPUT
  4306.  
  4307.     sname    <ENABLE_ECHO_INPUT>        ; -- x
  4308.     ctok    DOCONST                ; Con Mode constant value
  4309.     dd    ENABLE_ECHO_INPUT
  4310.  
  4311.     sname    <ENABLE_PROCESSED_INPUT>    ; -- x
  4312.     ctok    DOCONST                ; Con Mode constant value
  4313.     dd    ENABLE_PROCESSED_INPUT
  4314.  
  4315.     sname    <ENABLE_WINDOW_INPUT>        ; -- x
  4316.     ctok    DOCONST                ; Con Mode constant value
  4317.     dd    ENABLE_WINDOW_INPUT
  4318.  
  4319.     sname    <ENABLE_MOUSE_INPUT>        ; -- x
  4320.     ctok    DOCONST                ; Con Mode constant value
  4321.     dd    ENABLE_MOUSE_INPUT
  4322.  
  4323.     sname    <StdIn>                ; -- a-addr
  4324.     ctok    DOCONST                : Con stdin
  4325.     dd    stdIn
  4326.  
  4327.     sname    <StdOut>            ; -- a-addr
  4328.     ctok    DOCONST                : Con stdout
  4329.     dd    stdOut
  4330.  
  4331.     sname    <StdErr>            ; -- a-addr
  4332.     ctok    DOCONST                : Con stdErr
  4333.     dd    stdErr
  4334.  
  4335.     sname    <ConsoleMode>            ; -- a-addr
  4336.     ctok    DOCONST                ; Address of Con Mode variable
  4337.     dd    conMode                ; Implementation
  4338.  
  4339.     sname    <LastError>            ; -- a-addr
  4340.     ctok    DOCONST                ; Address of Last Error variable
  4341.     dd    lastError            ; Implementation
  4342.  
  4343.     sname    <GetConsoleMode>        ; -- LastErr | TRUE
  4344.     docode                    ; Implementation
  4345.     lea    eax,[dp+conMode]
  4346.     stdCall    _GetConsoleMode,<[dp+stdIn],eax>
  4347.     jmp    SHORT    retLastErr        ; returns to NEXT via doLastErr
  4348.  
  4349.     sname    <SetConsoleMode>        ; -- LastErr | TRUE
  4350.     docode                    ; Implementation
  4351.     mov    eax,[dp+conMode]
  4352.     stdCall    _SetConsoleMode,<[dp+stdIn],eax>
  4353.     jmp    SHORT    retLastErr        ; returns to NEXT via doLastErr
  4354.  
  4355. ; Set our local LastError variable either TRUE for success or to return from LastError, return same on stack
  4356. retLastErr:
  4357.     and    eax,eax                ; "C" TRUE is success
  4358.     je    rLE1                ; on failure, get error code
  4359.     mov    DWORD PTR lastError[dp],TRUE    ; success, return TRUE
  4360.     mov    eax,TRUE
  4361.     push    TRUE
  4362.     next                    ; No Windows error code has all bits set
  4363. rLE1:    stdCall    _GetLastError
  4364.     mov    lastError[dp],eax        ; save error return
  4365.     push    eax
  4366.     next
  4367.  
  4368. ;--( Startup & Signoff )
  4369.  
  4370.     zname    <LOGIN>
  4371.     docode
  4372.     stdCall    _WriteConsoleW,<[dp+stdErr],OFFSET FLAT:myMsg,myMsgLen,OFFSET FLAT:numWritten,0>
  4373.     next
  4374.  
  4375.     nname    <ABOUT>
  4376.     docode
  4377.     stdCall    _WriteConsoleW,<[dp+stdErr],OFFSET FLAT:gnuMsg,gnuMsgLen,OFFSET FLAT:numWritten,0>
  4378.     next
  4379.  
  4380.     zname    <LOGOFF>
  4381.     docode
  4382.     stdCall    _WriteConsoleW,<[dp+stdErr],OFFSET FLAT:byeMsg,byeMsgLen,OFFSET FLAT:numWritten,0>
  4383.     next
  4384.  
  4385.     nname    <COLD>
  4386.     ctok    NEST
  4387. cold:    ctok    GetConsoleMode    ; set up our variable that tracks the console input mode
  4388.     ctok    DROP        ; discard return
  4389.     ctok    DECIMAL        ; set number conversion base to decimal, set early to aid debugging
  4390.     ctok    FALSE
  4391.     ctok    BLK        ; input is not from a BLOCK file
  4392.     ctok    STORE
  4393.     ctok    FALSE
  4394.     ctok    SOURCE_ID    ; input is from keyboard
  4395.     ctok    STORE
  4396.     literal    ticktib
  4397.     ctok    TICK_TIB    ; set up pointer to terminal input buffer
  4398.     ctok    STORE
  4399.     ctok    FALSE
  4400.     ctok    NUMTIB        ; no chars in terminal input buffer
  4401.     ctok    STORE
  4402.     ctok    FALSE
  4403.     ctok    TO_IN        ; no index into zero chars
  4404.     ctok    STORE
  4405.     ctok    FALSE
  4406.     ctok    STATE        ; interpreting, not compiling
  4407.     ctok    EMPTYBUFFERS    ; clear block buffer(s)
  4408.     ctok    FALSE
  4409.     literal    blockFile
  4410.     ctok    STORE        ; no active block file
  4411.     ctok    STORE
  4412.     ctok     FIRSTCATCH    ; set up initial catch frame
  4413. ;!!!***!!!    
  4414. ;    ctok    BAREBOOTQ    ; is this a bare, not load-dictionary boot?
  4415. ;    compif    cold1        ; if yes, init search order
  4416.     ctok    ONLY        ; set default search order
  4417.     ctok    DEFINITIONS    ; set default compilation order
  4418.     ctok    SWORDLIST
  4419.     ctok    NWORDLIST
  4420.     ctok    FWORDLIST
  4421.     literal    3
  4422.     ctok    SET_ORDER
  4423. cold1:    ctok    LSHARP        ; set up number conversion buffer
  4424.     ctok    PAGE
  4425.     ctok    LOGIN        ; display signon message including copyright
  4426.     ctok    ABOUT
  4427.     ctok    okPrompt
  4428.     ctok    ABORT
  4429.  
  4430. ;--( Testing )
  4431.  
  4432. ;--( Bootup )
  4433.  
  4434. boot:                        ; initialize system
  4435.     stdCall    _LocalAlloc,<LMEM_FIXED,defDataSize+defDictSize>    ; get mem for user dictionary & data space
  4436.     push    eax                ; save mem handle
  4437.     stdCall    _LocalLock,eax            ; lock the mem
  4438.     mov    cp,eax                ; return if non-null is user dictionary, must test here
  4439.     lea    dp,[eax+defDictSize]        ; data space
  4440.     pop    eax                ; mem handle
  4441.     store    memHandle,eax            ; save copy of mem handle for later free
  4442.     store    ntConEBP,ebp            ; preserve EBP
  4443.     store    ntConESP,esp            ; preserve ESP
  4444.     lea    rp,[esp-dStackSize]        ; set return stack pointer
  4445.     store    rpzero,rp            ; save initial return stack
  4446.     stdCall    _GetStdHandle,STD_INPUT_HANDLE    ; return is handle or INVALID_HANDLE
  4447.     store    stdIn,eax            ; store handle
  4448.     stdCall    _GetStdHandle,STD_OUTPUT_HANDLE    ; return is handle or INVALID_HANDLE
  4449.     store    stdOut,eax            ; store handle
  4450.     stdCall    _GetStdHandle,STD_ERROR_HANDLE    ; return is handle or INVALID_HANDLE
  4451.     store    stdErr,eax            ; store handle
  4452.  
  4453. ; !!!***!!! for now, just fall thru here into bare_boot
  4454.  
  4455. bare_boot:                    ; if we aren't loading a saved image
  4456.     store    datap,varptr            ; set HERE
  4457.     store    dictp,0                ; offset end of dictionary
  4458.     store    wllink,<OFFSET FLAT:fw_SWORDLIST>    ; word list link
  4459.     mov    DWORD PTR [dp+flinkp],OFFSET FLAT:flinkptr    ; last link in FORTH-WORDLIST
  4460.     mov    DWORD PTR [dp+zlinkp],OFFSET FLAT:zlinkptr    ; last link in INTERNALS-WORDLIST
  4461.     mov    DWORD PTR [dp+nlinkp],OFFSET FLAT:nlinkptr    ; last link in NONSTANDARD-WORDLIST
  4462.     mov    DWORD PTR [dp+slinkp],OFFSET FLAT:slinkptr    ; last link in SYSTEM-WORDLIST
  4463.     mov    ecx,searchOrderSize        ; set up to clear search order
  4464.     xor    eax,eax                ; 0
  4465.     lea    edx,searchOrder[dp]        ; address of base of search order array
  4466. bb1:    mov    [edx],eax            ; erase a cell
  4467.     add    edx,cell            ; increment address
  4468.     loop    bb1                ; loop till done
  4469.  
  4470. dev_boot:
  4471.     mov    WORD PTR lastReadConW,UniNotAChar
  4472.     mov    ip,OFFSET FLAT:cold
  4473.     next
  4474.  
  4475. _mainCRTStartup    ENDP
  4476.  
  4477. _TEXT    ENDS
  4478.  
  4479. END
  4480.